mirror of
https://github.com/simon987/sist2.git
synced 2025-04-19 18:26:43 +00:00
330 lines
9.0 KiB
JavaScript
330 lines
9.0 KiB
JavaScript
export function mergeTooltips(slider, threshold, separator, fixTooltips) {
|
|
|
|
const isMobile = window.innerWidth <= 650;
|
|
if (isMobile) {
|
|
threshold = 25;
|
|
}
|
|
|
|
const textIsRtl = getComputedStyle(slider).direction === 'rtl';
|
|
const isRtl = slider.noUiSlider.options.direction === 'rtl';
|
|
const isVertical = slider.noUiSlider.options.orientation === 'vertical';
|
|
const tooltips = slider.noUiSlider.getTooltips();
|
|
const origins = slider.noUiSlider.getOrigins();
|
|
|
|
// Move tooltips into the origin element. The default stylesheet handles this.
|
|
tooltips.forEach(function (tooltip, index) {
|
|
if (tooltip) {
|
|
origins[index].appendChild(tooltip);
|
|
}
|
|
});
|
|
|
|
slider.noUiSlider.on('update', function (values, handle, unencoded, tap, positions) {
|
|
|
|
const pools = [[]];
|
|
const poolPositions = [[]];
|
|
const poolValues = [[]];
|
|
let atPool = 0;
|
|
|
|
// Assign the first tooltip to the first pool, if the tooltip is configured
|
|
if (tooltips[0]) {
|
|
pools[0][0] = 0;
|
|
poolPositions[0][0] = positions[0];
|
|
poolValues[0][0] = values[0];
|
|
}
|
|
|
|
for (let i = 1; i < positions.length; i++) {
|
|
if (!tooltips[i] || (positions[i] - positions[i - 1]) > threshold) {
|
|
atPool++;
|
|
pools[atPool] = [];
|
|
poolValues[atPool] = [];
|
|
poolPositions[atPool] = [];
|
|
}
|
|
|
|
if (tooltips[i]) {
|
|
pools[atPool].push(i);
|
|
poolValues[atPool].push(values[i]);
|
|
poolPositions[atPool].push(positions[i]);
|
|
}
|
|
}
|
|
|
|
pools.forEach(function (pool, poolIndex) {
|
|
const handlesInPool = pool.length;
|
|
|
|
for (let j = 0; j < handlesInPool; j++) {
|
|
const handleNumber = pool[j];
|
|
|
|
if (j === handlesInPool - 1) {
|
|
let offset = 0;
|
|
|
|
poolPositions[poolIndex].forEach(function (value) {
|
|
offset += 1000 - 10 * value;
|
|
});
|
|
|
|
const direction = isVertical ? 'bottom' : 'right';
|
|
const last = isRtl ? 0 : handlesInPool - 1;
|
|
const lastOffset = 1000 - 10 * poolPositions[poolIndex][last];
|
|
offset = (textIsRtl && !isVertical ? 100 : 0) + (offset / handlesInPool) - lastOffset;
|
|
|
|
// Center this tooltip over the affected handles
|
|
tooltips[handleNumber].innerHTML = poolValues[poolIndex].join(separator);
|
|
tooltips[handleNumber].style.display = 'block';
|
|
|
|
tooltips[handleNumber].style[direction] = offset + '%';
|
|
} else {
|
|
// Hide this tooltip
|
|
tooltips[handleNumber].style.display = 'none';
|
|
}
|
|
}
|
|
});
|
|
|
|
if (fixTooltips) {
|
|
const isMobile = window.innerWidth <= 650;
|
|
const len = isMobile ? 20 : 5;
|
|
|
|
if (positions[0] < len) {
|
|
tooltips[0].style.right = `${(1 - ((positions[0]) / len)) * -35}px`
|
|
} else {
|
|
tooltips[0].style.right = "0"
|
|
}
|
|
|
|
if (positions[1] > (100 - len)) {
|
|
tooltips[1].style.right = `${((positions[1] - (100 - len)) / len) * 35}px`
|
|
} else {
|
|
tooltips[1].style.right = "0"
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
export function burrow(table, addSelfDir, rootName) {
|
|
const root = {};
|
|
table.forEach(row => {
|
|
let layer = root;
|
|
|
|
row.taxonomy.forEach(key => {
|
|
layer[key] = key in layer ? layer[key] : {};
|
|
layer = layer[key];
|
|
});
|
|
if (Object.keys(layer).length === 0) {
|
|
layer["$size$"] = row.size;
|
|
} else if (addSelfDir) {
|
|
layer["."] = {
|
|
"$size$": row.size,
|
|
};
|
|
}
|
|
});
|
|
|
|
const descend = function (obj, depth) {
|
|
return Object.keys(obj).filter(k => k !== "$size$").map(k => {
|
|
const child = {
|
|
name: k,
|
|
depth: depth,
|
|
value: 0,
|
|
children: descend(obj[k], depth + 1)
|
|
};
|
|
if ("$size$" in obj[k]) {
|
|
child.value = obj[k]["$size$"];
|
|
}
|
|
return child;
|
|
});
|
|
};
|
|
|
|
return {
|
|
name: rootName,
|
|
children: descend(root, 1),
|
|
value: 0,
|
|
depth: 0,
|
|
}
|
|
}
|
|
|
|
|
|
export function ext(hit) {
|
|
return srcExt(hit._source)
|
|
}
|
|
|
|
export function srcExt(src) {
|
|
return Object.prototype.hasOwnProperty.call(src, "extension")
|
|
&& src["extension"] !== "" ? "." + src["extension"] : "";
|
|
}
|
|
|
|
export function strUnescape(str) {
|
|
let result = "";
|
|
|
|
for (let i = 0; i < str.length; i++) {
|
|
const c = str[i];
|
|
const next = str[i + 1];
|
|
|
|
if (c === "]") {
|
|
if (next === "]") {
|
|
result += c;
|
|
i += 1;
|
|
} else {
|
|
result += String.fromCharCode(parseInt(str.slice(i, i + 2), 16));
|
|
i += 2;
|
|
}
|
|
} else {
|
|
result += c;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const thresh = 1000;
|
|
const units = ["k", "M", "G", "T", "P", "E", "Z", "Y"];
|
|
|
|
export function humanFileSize(bytes) {
|
|
if (bytes === 0) {
|
|
return "0 B"
|
|
}
|
|
|
|
if (Math.abs(bytes) < thresh) {
|
|
return bytes + ' B';
|
|
}
|
|
let u = -1;
|
|
do {
|
|
bytes /= thresh;
|
|
++u;
|
|
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
|
|
|
|
return bytes.toFixed(1) + units[u];
|
|
}
|
|
|
|
export function humanTime(sec_num) {
|
|
sec_num = Math.floor(sec_num);
|
|
const hours = Math.floor(sec_num / 3600);
|
|
const minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
|
const seconds = sec_num - (hours * 3600) - (minutes * 60);
|
|
|
|
if (sec_num < 60) {
|
|
return `${sec_num}s`
|
|
}
|
|
|
|
if (sec_num < 3600) {
|
|
return `${minutes < 10 ? "0" : ""}${minutes}:${seconds < 10 ? "0" : ""}${seconds}`;
|
|
}
|
|
|
|
return `${hours < 10 ? "0" : ""}${hours}:${minutes < 10 ? "0" : ""}${minutes}:${seconds < 10 ? "0" : ""}${seconds}`;
|
|
}
|
|
|
|
export function humanDate(numMilis) {
|
|
const date = (new Date(numMilis * 1000));
|
|
return date.getUTCFullYear() + "-" + ("0" + (date.getUTCMonth() + 1)).slice(-2) + "-" + ("0" + date.getUTCDate()).slice(-2)
|
|
|
|
}
|
|
|
|
export function lum(c) {
|
|
c = c.substring(1);
|
|
const rgb = parseInt(c, 16);
|
|
const r = (rgb >> 16) & 0xff;
|
|
const g = (rgb >> 8) & 0xff;
|
|
const b = (rgb >> 0) & 0xff;
|
|
|
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
}
|
|
|
|
|
|
export function getSelectedTreeNodes(tree) {
|
|
const selectedNodes = new Set();
|
|
|
|
const selected = tree.selected();
|
|
|
|
for (let i = 0; i < selected.length; i++) {
|
|
|
|
if (selected[i].id === "any") {
|
|
return ["any"]
|
|
}
|
|
|
|
//Only get children
|
|
if (selected[i].text.indexOf("(") !== -1) {
|
|
if (selected[i].values) {
|
|
selectedNodes.add(selected[i].values.slice(-1)[0]);
|
|
} else {
|
|
selectedNodes.add(selected[i].id);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Array.from(selectedNodes);
|
|
}
|
|
|
|
export function getTreeNodeAttributes(tree) {
|
|
const nodes = tree.selectable();
|
|
const attributes = {};
|
|
|
|
for (let i = 0; i < nodes.length; i++) {
|
|
|
|
let id = null;
|
|
|
|
if (nodes[i].text.indexOf("(") !== -1 && nodes[i].values) {
|
|
id = nodes[i].values.slice(-1)[0];
|
|
} else {
|
|
id = nodes[i].id
|
|
}
|
|
|
|
attributes[id] = {
|
|
checked: nodes[i].itree.state.checked,
|
|
collapsed: nodes[i].itree.state.collapsed,
|
|
}
|
|
}
|
|
|
|
return attributes;
|
|
}
|
|
|
|
|
|
export function serializeMimes(mimes) {
|
|
if (mimes.length === 0) {
|
|
return undefined;
|
|
}
|
|
return mimes.map(mime => compressMime(mime)).join("");
|
|
}
|
|
|
|
export function deserializeMimes(mimeString) {
|
|
return mimeString
|
|
.replaceAll(/([IVATUF])/g, "$$$&")
|
|
.split("$")
|
|
.map(mime => decompressMime(mime))
|
|
.slice(1) // Ignore the first (empty) token
|
|
}
|
|
|
|
export function compressMime(mime) {
|
|
return mime
|
|
.replace("image/", "I")
|
|
.replace("video/", "V")
|
|
.replace("application/", "A")
|
|
.replace("text/", "T")
|
|
.replace("audio/", "U")
|
|
.replace("font/", "F")
|
|
.replace("+", ",")
|
|
.replace("x-", "X")
|
|
}
|
|
|
|
export function decompressMime(mime) {
|
|
return mime
|
|
.replace("I", "image/")
|
|
.replace("V", "video/")
|
|
.replace("A", "application/")
|
|
.replace("T", "text/")
|
|
.replace("U", "audio/")
|
|
.replace("F", "font/")
|
|
.replace(",", "+")
|
|
.replace("X", "x-")
|
|
}
|
|
|
|
export function randomSeed() {
|
|
return Math.round(Math.random() * 100000);
|
|
}
|
|
|
|
export function sid(doc) {
|
|
if (doc._id.includes(".")) {
|
|
return doc._id
|
|
}
|
|
|
|
const num = BigInt(doc._id);
|
|
|
|
const indexId = (num >> BigInt(32));
|
|
const docId = num & BigInt(0xFFFFFFFF);
|
|
|
|
return indexId.toString(16).padStart(8, "0") + "." + docId.toString(16).padStart(8, "0");
|
|
}
|