1
0
dwelling-files/web/assets/js/main.js

308 lines
8.8 KiB
JavaScript

document.getElementById("instruction").classList.remove("hidden");
//// OVERLAY FOR VIEWING MEDIA FILES
const overlay = document.getElementById("overlay");
const overlay_content = overlay.children[1];
const overlay_label = overlay.children[2];
const g_tbody = document.getElementsByTagName('tbody')[0];
let g_first_row = g_tbody.firstChild;
let g_last_row = g_tbody.lastChild;
const g_back_row = document.getElementsByTagName("tr")[1];
let g_scale = 1;
let g_oc_offset = [0, 0];
let g_oc_translate = [0, 0];
let g_current_row = g_back_row;
if (localStorage.getItem('audio_volume') == null)
localStorage['audio_volume'] = 0.5;
function overlayClose() {
overlay_content.firstChild.remove();
overlay.style.visibility = "hidden";
g_scale = 1;
g_oc_offset = g_oc_translate = [0, 0];
}
overlay.addEventListener("mouseup", e => {
if (e.target.tagName === "DIV" && e.button === 0) overlayClose(); });
overlay_content.addEventListener("wheel", e => {
e.preventDefault();
g_scale = Math.min(Math.max(0.25, g_scale + (e.deltaY * -0.001)), 4);
e.target.style.transform =
`translate(${g_oc_translate[0]}px, ${g_oc_translate[1]}px) scale(${g_scale})`;
});
overlay_content.addEventListener("mousedown", e => {
if (e.buttons !== 1) return;
e.preventDefault();
g_oc_offset = [e.offsetX, e.offsetY];
});
overlay_content.addEventListener("mousemove", e => {
if (e.buttons !== 1) return;
e.preventDefault();
g_oc_translate[0] = e.clientX - e.target.x - g_oc_offset[0];
g_oc_translate[1] = e.clientY - e.target.y - g_oc_offset[1];
e.target.style.transform =
`translate(${g_oc_translate[0]}px, ${g_oc_translate[1]}px) scale(${g_scale})`;
});
function determineMediaElement(path) {
path = path.toLowerCase();
if (["webm", "mp4", "mov"].some(ext => path.endsWith(ext)))
return "video";
else if (["mp3", "flac", "opus", "ogg", "m4a"].some(ext => path.endsWith(ext)))
return "audio";
else if (["jpg", "jpeg", "gif", "png", "bmp", "webp"].some(ext => path.endsWith(ext)))
return "img";
return undefined;
}
function overlaySet(pathname, media_type_element) {
if (media_type_element === undefined)
return false;
if (overlay_content.children.length != 0) {
g_oc_offset = g_oc_translate = [0, 0];
g_scale = 1;
}
const media_element = document.createElement(media_type_element);
media_element.src = pathname;
if (media_type_element !== "img") {
media_element.autoplay = media_element.controls = true;
media_element.addEventListener("volumechange", e => {
localStorage['audio_volume'] = e.target.volume; });
media_element.volume = localStorage["audio_volume"];
media_element.addEventListener("ended", e => { if (overlay_autoplay.checked) b_next.click(); });
}
overlay_label.textContent = decodeURI(pathname.substr(pathname.lastIndexOf("/") + 1));
overlay_content.replaceChildren(media_element);
overlay.style.visibility = "visible";
return true;
}
function getSibling(isNext = true, upDown = false) {
if (upDown && g_current_row == g_back_row)
g_current_row = isNext ? g_first_row : g_last_row;
else
g_current_row = isNext ?
( (g_current_row.nextSibling === null) ?
(upDown ? g_back_row : g_first_row) : g_current_row.nextSibling )
: ( (g_current_row.previousSibling === null) ?
(upDown ? g_back_row : g_last_row) : g_current_row.previousSibling );
return g_current_row;
}
const [b_prev, b_next] = overlay.getElementsByTagName("button");
b_prev.addEventListener("click", e => {
do {
getSibling(false, false);
} while (g_current_row.classList.contains("hidden")
|| !overlaySet(g_current_row.firstChild.firstChild.pathname,
determineMediaElement(g_current_row.firstChild.firstChild.pathname)));
g_current_row.firstChild.firstChild.focus();
e.preventDefault();
});
b_next.addEventListener("click", e => {
do {
getSibling(true, false);
} while (g_current_row.classList.contains("hidden")
|| !overlaySet(g_current_row.firstChild.firstChild.pathname,
determineMediaElement(g_current_row.firstChild.firstChild.pathname)));
g_current_row.firstChild.firstChild.focus();
e.preventDefault();
});
Array.from(g_tbody.children)
.forEach(v => {
if (v.lastChild.innerHTML === "DIR") return;
v.firstChild.firstChild.addEventListener("click", e => {
g_current_row = e.target.parentNode.parentNode;
if (overlaySet(e.target.pathname, determineMediaElement(e.target.pathname)))
e.preventDefault();
});
});
overlay_autoplay = document.getElementsByName("autoplay")[0];
if (localStorage.getItem('autoplay') == null)
localStorage['autoplay'] = overlay_autoplay.checked = false;
overlay_autoplay.addEventListener("change", e => {
localStorage['autoplay'] = e.target.checked;
const media_element = overlay_content.firstChild
if (e.target.checked && media_element !== undefined)
if (media_element.tagName === "AUDIO" || media_element.tagName === "VIDEO")
if (media_element.ended)
b_next.click();
});
//// KEYBOARD HANDLING
window.addEventListener("keydown", e => {
if (e.isComposing)
return;
if (overlay.style.visibility === "hidden" || overlay.style.visibility === "") {
switch (e.code) {
case "Backspace": if (e.ctrlKey) window.location = "../"; break;
case "Home": g_current_row = g_back_row; g_back_row.firstChild.firstChild.focus(); break;
case "End": g_current_row = g_last_row; g_last_row.firstChild.firstChild.focus(); break;
case "ArrowUp":
case "ArrowLeft":
e.preventDefault();
getSibling(false, true);
g_current_row.firstChild.firstChild.focus();
break;
case "ArrowDown":
case "ArrowRight":
e.preventDefault();
getSibling(true, true);
g_current_row.firstChild.firstChild.focus();
break;
}
return;
}
switch (e.code) {
case "ArrowUp":
case "ArrowLeft":
e.preventDefault();
b_prev.click();
break;
case "ArrowDown":
case "ArrowRight":
e.preventDefault();
b_next.click();
break;
case "Escape": overlayClose(); break;
case "Space":
e.preventDefault();
const el = overlay_content.firstChild;
if (el.paused !== undefined)
el.paused ? el.play() : el.pause();
}
});
//// FILTERING
document.getElementsByName("filter")[0].classList.remove("hidden");
function filter(sub) {
const table = g_tbody.children;
for (let j = 0; j < table.length; ++j)
table[j].classList.toggle("hidden",
!(sub === "" || table[j].firstChild.firstChild.innerText.toLowerCase().indexOf(sub) != -1));
}
document.getElementsByName("filter")[0].addEventListener("input", e => filter(e.target.value.toLowerCase()));
//// SORT BY COLUMN
const units = {"B": 0, "KiB": 1, "MiB": 2, "GiB": 3, "TiB": 4};
const [thead_name, thead_date, thead_size] = document.getElementsByTagName('thead')[0]
.children[0].children;
let g_sort_reverse = false;
thead_name.classList.toggle("clickable");
thead_name.addEventListener('click', e => {
e.preventDefault();
sortTable((a,b) => {
const a_name = a.children[0].textContent.toLowerCase();
const b_name = b.children[0].textContent.toLowerCase();
return a_name < b_name ? -1 : a_name > b_name ? 1 : 0;
}, null, null, thead_name, [thead_date, thead_size]);
g_first_row = g_tbody.firstChild;
g_last_row = g_tbody.lastChild;
});
thead_date.classList.toggle("clickable");
thead_date.addEventListener('click', e => {
e.preventDefault();
sortTable((a,b) => {
const a_date = new Date(a.children[1].textContent.slice(0, -4));
const b_date = new Date(b.children[1].textContent.slice(0, -4));
return a_date - b_date;
}, null, null, thead_date, [thead_name, thead_size]);
g_first_row = g_tbody.firstChild;
g_last_row = g_tbody.lastChild;
});
function sizeToBytes(size, unit) {
if (units[unit] == 0) return size;
for (let i = 0; i <= units[unit]; ++i) size *= 1024;
return size;
}
thead_size.classList.toggle("clickable");
thead_size.addEventListener('click', e => {
e.preventDefault();
sortTable(
(a,b) => {
if (a.textContent == "DIR")
return 1;
let [a_size, a_unit] = a.children[2].textContent.split(" ");
let [b_size, b_unit] = b.children[2].textContent.split(" ");
return sizeToBytes(+a_size, a_unit) - sizeToBytes(+b_size, b_unit);
},
e => e.children[2].textContent == "DIR",
e => e.children[2].textContent != "DIR",
thead_size, [thead_name, thead_date]);
g_first_row = g_tbody.firstChild;
g_last_row = g_tbody.lastChild;
});
function sortTable(compareFn, filterFn, filterNegFn, target, other) {
let records = Array.from(g_tbody.children);
let dirs = [];
if (filterFn != null) {
dirs = records.filter(filterFn);
records = records.filter(filterNegFn);
}
records.sort(compareFn);
g_tbody.textContent = "";
other.forEach(v => {
v.classList.remove("sort-up");
v.classList.remove("sort-down");
});
if (filterFn != null)
g_tbody.append(...dirs);
if (g_sort_reverse) {
g_tbody.append(...records.reverse());
target.classList.add("sort-up");
target.classList.remove("sort-down");
} else {
g_tbody.append(...records);
target.classList.add("sort-down");
target.classList.remove("sort-up");
}
g_sort_reverse = !g_sort_reverse;
}