-
-
Filter 1:
-
+
+
Type: All None
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -177,6 +151,7 @@
+
diff --git a/js/drag_drop_touch.js b/js/drag_drop_touch.js
new file mode 100644
index 0000000..4cf6cb7
--- /dev/null
+++ b/js/drag_drop_touch.js
@@ -0,0 +1,8 @@
+/*
+ DragDropTouch by Bernardo Castilho
+ https://github.com/Bernardo-Castilho/dragdroptouch
+ MIT License
+
+ Note: it only works on a real phone for some reason, it doesn't work on desktop browser simulations of phones for some reason.
+*/
+var DragDropTouch;!function(t){"use strict";var e=function(){function t(){this._dropEffect="move",this._effectAllowed="all",this._data={}}return Object.defineProperty(t.prototype,"dropEffect",{get:function(){return this._dropEffect},set:function(t){this._dropEffect=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"effectAllowed",{get:function(){return this._effectAllowed},set:function(t){this._effectAllowed=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"types",{get:function(){return Object.keys(this._data)},enumerable:!0,configurable:!0}),t.prototype.clearData=function(t){null!=t?delete this._data[t.toLowerCase()]:this._data={}},t.prototype.getData=function(t){return this._data[t.toLowerCase()]||""},t.prototype.setData=function(t,e){this._data[t.toLowerCase()]=e},t.prototype.setDragImage=function(t,e,s){var o=i._instance;o._imgCustom=t,o._imgOffset={x:e,y:s}},t}();t.DataTransfer=e;var i=function(){function t(){if(this._lastClick=0,t._instance)throw"DragDropTouch instance already created.";var e=!1;if(document.addEventListener("test",function(){},{get passive(){return e=!0,!0}}),navigator.maxTouchPoints){var i=document,s=this._touchstart.bind(this),o=this._touchmove.bind(this),n=this._touchend.bind(this),r=!!e&&{passive:!1,capture:!1};i.addEventListener("touchstart",s,r),i.addEventListener("touchmove",o,r),i.addEventListener("touchend",n),i.addEventListener("touchcancel",n)}}return t.getInstance=function(){return t._instance},t.prototype._touchstart=function(e){var i=this;if(this._shouldHandle(e)){if(Date.now()-this._lastClick
t._PRESSHOLDMARGIN},t.prototype._shouldStartDragging=function(e){var i=this._getDelta(e);return i>t._THRESHOLD||t._ISPRESSHOLDMODE&&i>=t._PRESSHOLDTHRESHOLD},t.prototype._reset=function(){this._destroyImage(),this._dragSource=null,this._lastTouch=null,this._lastTarget=null,this._ptDown=null,this._isDragEnabled=!1,this._isDropZone=!1,this._dataTransfer=new e,clearInterval(this._pressHoldInterval)},t.prototype._getPoint=function(t,e){return t&&t.touches&&(t=t.touches[0]),{x:e?t.pageX:t.clientX,y:e?t.pageY:t.clientY}},t.prototype._getDelta=function(e){if(t._ISPRESSHOLDMODE&&!this._ptDown)return 0;var i=this._getPoint(e);return Math.abs(i.x-this._ptDown.x)+Math.abs(i.y-this._ptDown.y)},t.prototype._getTarget=function(t){for(var e=this._getPoint(t),i=document.elementFromPoint(e.x,e.y);i&&"none"==getComputedStyle(i).pointerEvents;)i=i.parentElement;return i},t.prototype._createImage=function(e){this._img&&this._destroyImage();var i=this._imgCustom||this._dragSource;if(this._img=i.cloneNode(!0),this._copyStyle(i,this._img),this._img.style.top=this._img.style.left="-9999px",!this._imgCustom){var s=i.getBoundingClientRect(),o=this._getPoint(e);this._imgOffset={x:o.x-s.left,y:o.y-s.top},this._img.style.opacity=t._OPACITY.toString()}this._moveImage(e),document.body.appendChild(this._img)},t.prototype._destroyImage=function(){this._img&&this._img.parentElement&&this._img.parentElement.removeChild(this._img),this._img=null,this._imgCustom=null},t.prototype._moveImage=function(t){var e=this;requestAnimationFrame(function(){if(e._img){var i=e._getPoint(t,!0),s=e._img.style;s.position="absolute",s.pointerEvents="none",s.zIndex="999999",s.left=Math.round(i.x-e._imgOffset.x)+"px",s.top=Math.round(i.y-e._imgOffset.y)+"px"}})},t.prototype._copyProps=function(t,e,i){for(var s=0;s 200) {break;}
let item = items_copy[i].itemExp;
let box = make_elem('div', ['col-lg-3', 'col-sm-6', 'p-2'], {id: 'item'+i});
- //box.addEventListener("dblclick", function() {set_item(item);}); TODO: ??
let bckgrdbox = make_elem("div", ["dark-7", "rounded", "px-2", "col-auto"], {id: 'item'+i+'b'});
box.append(bckgrdbox);
@@ -141,47 +137,69 @@ let expr_parser;
function do_item_search() {
window.scrollTo(0, 0);
let queries = [];
- queries.push('f:name?="'+document.getElementById("item-name-choice").value.trim()+'"');
- const cat_or_type = document.getElementById("item-category-choice").value;
- if (item_types.includes(cat_or_type)) {
- queries.push('f:type="'+cat_or_type+'"');
- }
- else if (item_categories.includes(cat_or_type)) {
- queries.push('f:cat="'+cat_or_type+'"');
+ // name
+ if (document.getElementById("item-name-choice").value != "") {
+ queries.push("f:name?=\"" + document.getElementById("item-name-choice").value.trim() + "\"");
}
- let rarity = document.getElementById("item-rarity-choice").value;
- if (rarity) {
- if (rarity === "ANY") {
-
- }
- else if (rarity === "Sane") {
- queries.push('f:tiername!="mythic"');
- }
- else {
- queries.push('f:tiername="'+rarity+'"');
+ // types
+ let allTypes = true;
+ let typeQuery = "f:("
+ for (const type of Object.keys(types)) {
+ if (types[type]) {
+ typeQuery += "type=\"" + type + "\"|";
+ } else {
+ allTypes = false;
}
}
+ if (!allTypes) {
+ queries.push(typeQuery.substring(0, typeQuery.length - 1) + ")");
+ }
- let level_raw = document.getElementById("item-level-choice").value;
- if (!level_raw) { level_raw = '1-106'; };
- const level_dat = level_raw.split("-");
- queries.push('f:(lvl>='+parseInt(level_dat[0])+'&lvl<='+parseInt(level_dat[1])+')');
+ // rarities
+ let allRarities = true;
+ let rarityQuery = "f:("
+ for (const rarity of Object.keys(rarities)) {
+ if (rarities[rarity]) {
+ rarityQuery += "tiername=\"" + rarity + "\"|";
+ } else {
+ allRarities = false;
+ }
+ }
+ if (!allRarities) {
+ queries.push(rarityQuery.substring(0, rarityQuery.length - 1) + ")");
+ }
- for (let i = 1; i <= 4; ++i) {
- let raw_dat = document.getElementById("filter"+i+"-choice").value;
- let filter_dat = translate_mappings[raw_dat];
- if (filter_dat !== undefined) {
- queries.push("s:"+filter_dat);
- queries.push("f:"+filter_dat+"!=0");
- continue;
+ // filters
+ for (const filter of filters) {
+ let min = parseInt(filter.min_elem.value);
+ let max = parseInt(filter.max_elem.value);
+ if (min > max) {
+ continue; // invalid range
}
- filter_dat = special_mappings[raw_dat];
- if (filter_dat !== undefined) {
- queries.push(filter_dat);
- continue;
+ let zero_in_min_max = (isNaN(min) || min <= 0) && (isNaN(max) || max >= 0);
+
+ let raw_name = filter.input_elem.value;
+ let filter_name = translate_mappings[raw_name];
+ if (filter_name === undefined) {
+ filter_name = special_mappings[raw_name];
+ if (filter_name === undefined) {
+ continue; // not a valid filter
+ }
+ filter_name = "(" + filter_name + ")";
}
+
+ if (!isNaN(min)) {
+ queries.push("f:" + filter_name + ">=" + min);
+ }
+ if (!isNaN(max)) {
+ queries.push("f:" + filter_name + "<=" + max);
+ }
+ if (zero_in_min_max) {
+ queries.push("f:" + filter_name + "!=0");
+ }
+ queries.push("s:" + (filter.ascending ? "0-" : "") + filter_name);
}
let filter_query = "true";
@@ -218,67 +236,221 @@ function do_item_search() {
displayItems(results);
}
-function reset_item_search() {
- const reset_fields = ["item-name-choice", "item-category-choice", "item-rarity-choice", "item-level-choice", "filter1-choice", "filter2-choice", "filter3-choice", "filter4-choice"]
- for (const field of reset_fields) {
- document.getElementById(field).value = "";
- }
-}
-
function init_items() {
search_db = items.filter( i => ! i.remapID ).map( i => [i, expandItem(i, [])] );
expr_parser = new ExprParser(itemQueryProps, itemQueryFuncs);
- //init dropdowns
- let filter_inputs = new Map([["item-category", ["ALL", "armor", "helmet", "chestplate", "leggings", "boots", "accessory", "ring", "bracelet", "necklace", "weapon", "wand", "spear", "bow", "dagger", "relik"]],
- ["item-rarity", ["ANY", "Normal", "Unique", "Set", "Rare", "Legendary", "Fabled", "Mythic", "Sane"]],
- ["filter1", item_filters],
- ["filter2", item_filters],
- ["filter3", item_filters],
- ["filter4", item_filters]]);
- for (const [field, data] of filter_inputs) {
- let field_choice = document.getElementById(field+"-choice");
- // show dropdown on click
- field_choice.onclick = function() {field_choice.dispatchEvent(new Event('input', {bubbles:true}));};
- filter_inputs.set(field, new autoComplete({
- data: {
- src: data,
- },
- threshold: 0,
- selector: "#"+ field +"-choice",
- wrapper: false,
- resultsList: {
- maxResults: 100,
- tabSelect: true,
- noResults: true,
- class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm",
- element: (list, data) => {
- let position = document.getElementById(field+'-choice').getBoundingClientRect();
- list.style.top = position.bottom + window.scrollY +"px";
- list.style.left = position.x+"px";
- list.style.width = position.width+"px";
- list.style.maxHeight = position.height * 4 +"px";
- if (!data.results.length) {
- const message = make_elem('li', ['scaled-font'], {textContent: "No results found!"});
- list.prepend(message);
+ // init type buttons
+ for (const type of Object.keys(types)) {
+ document.getElementById("type-" + type).addEventListener("click", function() {
+ types[type] = !types[type];
+ this.classList.toggle("type-selected");
+ });
+ }
+ document.getElementById("all-types").addEventListener("click", function() {
+ for (const type of Object.keys(types)) {
+ types[type] = true;
+ document.getElementById("type-" + type).classList.add("type-selected");
+ }
+ });
+ document.getElementById("none-types").addEventListener("click", function() {
+ for (const type of Object.keys(types)) {
+ types[type] = false;
+ document.getElementById("type-" + type).classList.remove("type-selected");
+ }
+ });
+
+ // init rarity buttons
+ for (const rarity of Object.keys(rarities)) {
+ document.getElementById("rarity-" + rarity).addEventListener("click", function() {
+ rarities[rarity] = !rarities[rarity];
+ this.classList.toggle("rarity-selected");
+ });
+ }
+ document.getElementById("all-rarities").addEventListener("click", function() {
+ for (const rarity of Object.keys(rarities)) {
+ rarities[rarity] = true;
+ document.getElementById("rarity-" + rarity).classList.add("rarity-selected");
+ }
+ });
+ document.getElementById("none-rarities").addEventListener("click", function() {
+ for (const rarity of Object.keys(rarities)) {
+ rarities[rarity] = false;
+ document.getElementById("rarity-" + rarity).classList.remove("rarity-selected");
+ }
+ });
+
+ // filters
+ document.getElementById("add-filter").addEventListener("click", create_filter);
+ create_filter();
+ filters[0].input_elem.value = "Combat Level";
+ init_filter_drag();
+}
+
+function reset_item_search() {
+ document.getElementById("item-name-choice").value = "";
+ document.getElementById("all-types").click();
+ document.getElementById("all-rarities").click();
+}
+
+function create_filter() {
+ let data = {ascending: false};
+
+ let row = make_elem("div", ["row", "filter-row"], {});
+ let col = make_elem("div", ["col"], {});
+ row.appendChild(col);
+ data.div = row;
+
+ let reorder_img = make_elem("img", ["reorder-filter"], {src: "../media/icons/3-lines.svg", draggable: "true"});
+ col.appendChild(reorder_img);
+
+ let filter_input = make_elem("input",
+ ["col", "border-dark", "text-light", "dark-5", "rounded", "scaled-font", "form-control", "form-control-sm", "filter-input"],
+ {id: "filter-input-" + filter_id_counter, type: "text", placeholder: "Filter"}
+ );
+ filter_id_counter++;
+ col.appendChild(filter_input);
+ data.input_elem = filter_input;
+
+ let asc_desc = make_elem("div", [], {style: "cursor: pointer; display: inline-block;"});
+ asc_desc.appendChild(make_elem("img", ["desc-icon", "asc-sel"], {src: "../media/icons/triangle.svg"}));
+ asc_desc.appendChild(make_elem("img", ["asc-icon"], {src: "../media/icons/triangle.svg"}));
+ asc_desc.addEventListener("click", function() {
+ data.ascending = !data.ascending;
+ asc_desc.children[0].classList.toggle("asc-sel");
+ asc_desc.children[1].classList.toggle("asc-sel");
+ });
+ col.appendChild(asc_desc);
+
+ let min = make_elem("input",
+ ["col", "border-dark", "text-light", "dark-5", "rounded", "scaled-font", "form-control", "form-control-sm", "min-max-input"],
+ {type: "number", placeholder: "-\u221E"}
+ );
+ col.appendChild(min);
+ data.min_elem = min;
+
+ let to = make_elem("span", [], {innerHTML: " to "});
+ col.appendChild(to);
+
+ let max = make_elem("input",
+ ["col", "border-dark", "text-light", "dark-5", "rounded", "scaled-font", "form-control", "form-control-sm", "min-max-input"],
+ {type: "number", placeholder: "\u221E"}
+ );
+ col.appendChild(max);
+ data.max_elem = max;
+
+ document.getElementById("filter-container").insertBefore(row, document.getElementById("add-filter").parentElement);
+
+ filters.push(data);
+ init_filter_dropdown(data);
+}
+
+let currently_dragging = null;
+function init_filter_drag() {
+ let container = document.getElementById("filter-container");
+
+ container.addEventListener("dragstart", function(e) {
+ if (e.path[0].classList.contains("reorder-filter")) {
+ currently_dragging = filters[Array.from(e.path[3].children).indexOf(e.path[2]) - 1];
+ } else {
+ e.preventDefault();
+ }
+ });
+
+ container.addEventListener("dragenter", function(e) {
+ e.preventDefault();
+ });
+
+ container.addEventListener("dragleave", function(e) {
+ e.preventDefault();
+ });
+
+ container.addEventListener("dragend", function(e) {
+ e.preventDefault();
+ for (const el of document.getElementsByClassName("filter-dragged-over")) {
+ el.classList.remove("filter-dragged-over");
+ }
+ currently_dragging = null;
+ });
+
+ container.addEventListener("dragover", function(e) {
+ e.preventDefault();
+ for (const el of document.getElementsByClassName("filter-dragged-over")) {
+ el.classList.remove("filter-dragged-over");
+ }
+ if (!e.path.includes(currently_dragging.div)) {
+ for (let i = 0; i < e.path.length; i++) {
+ if (e.path[i].classList.contains("filter-row")) {
+ e.path[i].classList.add("filter-dragged-over");
+ break;
+ }
+ }
+ }
+ });
+
+ container.addEventListener("drop", function(e) {
+ e.preventDefault();
+ for (const el of document.getElementsByClassName("filter-dragged-over")) {
+ el.classList.remove("filter-dragged-over");
+ }
+ if (!e.path.includes(currently_dragging.div)) {
+ for (let i = 0; i < e.path.length; i++) {
+ if (e.path[i].classList.contains("filter-row")) {
+ let old_index = filters.indexOf(currently_dragging);
+ let new_index = Array.from(e.path[i + 1].children).indexOf(e.path[i]) - 1;
+ filters.splice(old_index, 1);
+ filters.splice(new_index, 0, currently_dragging);
+ currently_dragging.div.remove();
+ container.insertBefore(currently_dragging.div, container.children[new_index + 1]);
+ break;
+ }
+ }
+ }
+ currently_dragging = null;
+ });
+}
+
+function init_filter_dropdown(filter) {
+ let field_choice = filter.input_elem;
+ field_choice.onclick = function() {field_choice.dispatchEvent(new Event('input', {bubbles:true}));};
+ filter.autoComplete = new autoComplete({
+ data: {
+ src: item_filters,
+ },
+ threshold: 0,
+ selector: "#" + field_choice.id,
+ wrapper: false,
+ resultsList: {
+ maxResults: 100,
+ tabSelect: true,
+ noResults: true,
+ class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm",
+ element: (list, data) => {
+ let position = field_choice.getBoundingClientRect();
+ list.style.top = position.bottom + window.scrollY +"px";
+ list.style.left = position.x+"px";
+ list.style.width = position.width+"px";
+ list.style.maxHeight = position.height * 4 +"px";
+ if (!data.results.length) {
+ const message = make_elem('li', ['scaled-font'], {textContent: "No results found!"});
+ list.prepend(message);
+ };
+ },
+ },
+ resultItem: {
+ class: "scaled-font search-item",
+ selected: "dark-5",
+ },
+ events: {
+ input: {
+ selection: (event) => {
+ if (event.detail.selection.value) {
+ event.target.value = event.detail.selection.value;
};
},
},
- resultItem: {
- class: "scaled-font search-item",
- selected: "dark-5",
- },
- events: {
- input: {
- selection: (event) => {
- if (event.detail.selection.value) {
- event.target.value = event.detail.selection.value;
- };
- },
- },
- }
- }));
- }
+ }
+ });
}
(async function() {
diff --git a/media/icons/3-lines.svg b/media/icons/3-lines.svg
new file mode 100644
index 0000000..b1c0a2d
--- /dev/null
+++ b/media/icons/3-lines.svg
@@ -0,0 +1,8 @@
+
diff --git a/media/icons/triangle.svg b/media/icons/triangle.svg
new file mode 100644
index 0000000..0c07a50
--- /dev/null
+++ b/media/icons/triangle.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file