ui stuff, proxy?, and whatever else
This commit is contained in:
154
js/loader.js
154
js/loader.js
@ -5,7 +5,9 @@ let topElements = [];
|
||||
let isDev = [];
|
||||
let pageData;
|
||||
let starredGames = [];
|
||||
let recentGames = [];
|
||||
let globalPlays = null;
|
||||
let selectedTags = new Set();
|
||||
|
||||
function getHiddenGames() {
|
||||
try {
|
||||
@ -16,12 +18,22 @@ function getHiddenGames() {
|
||||
}
|
||||
}
|
||||
|
||||
function getRecentlyPlayed() {
|
||||
try {
|
||||
const parsed = JSON.parse(localStorage.getItem("selenite.recentlyPlayed") || "[]");
|
||||
return parsed;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function loadGames() {
|
||||
if (type == "g") pageData = { path: "/resources/games.json", prefix: "semag", type: "g" };
|
||||
else if (type == "a") pageData = { path: "/resources/apps.json", prefix: "sppa", type: "a" };
|
||||
else { sAlert("this is not valid"); return; }
|
||||
|
||||
let data = await (await fetch(pageData.path)).json();
|
||||
const topGamesDisabled = localStorage.getItem("selenite.disableTopGames") == "true";
|
||||
|
||||
data.forEach((g, i) => { g._key = g.name.toUpperCase(); g._index = i; });
|
||||
data.sort((a, b) => a._key < b._key ? -1 : a._key > b._key ? 1 : 0);
|
||||
@ -50,6 +62,7 @@ async function loadGames() {
|
||||
newElement.dataset.name = element._key;
|
||||
newElement.dataset.top = element.tags && element.tags.includes("top") ? "1" : "";
|
||||
newElement.dataset.index = element._index;
|
||||
newElement.dataset.tags = element.tags ? element.tags.join(",") : "";
|
||||
newElement.className = "game";
|
||||
newElement.href = `/loader.html?title=${encodeURIComponent(element.name)}&dir=${element.directory}&img=${element.image}&type=${pageData.type}`;
|
||||
|
||||
@ -73,6 +86,7 @@ async function loadGames() {
|
||||
newElement.appendChild(image);
|
||||
newElement.appendChild(holder);
|
||||
newElement.appendChild(warnings);
|
||||
holder.appendChild(star);
|
||||
|
||||
if (element.tags) {
|
||||
[["18+", "thirteen", "18+"], ["13+", "thirteen", "13+"],
|
||||
@ -91,18 +105,16 @@ async function loadGames() {
|
||||
w.className = "thirteen";
|
||||
warnings.appendChild(w);
|
||||
}
|
||||
if (element.tags.includes("top")) {
|
||||
if (element.tags.includes("top") && !topGamesDisabled) {
|
||||
topFragment.appendChild(newElement);
|
||||
topElements.push(newElement);
|
||||
} else {
|
||||
gamesFragment.appendChild(newElement);
|
||||
gameElements.push(newElement);
|
||||
holder.appendChild(star);
|
||||
}
|
||||
} else {
|
||||
gamesFragment.appendChild(newElement);
|
||||
gameElements.push(newElement);
|
||||
holder.appendChild(star);
|
||||
}
|
||||
|
||||
elements.push(newElement);
|
||||
@ -117,9 +129,10 @@ async function loadGames() {
|
||||
if (topGElement) topGElement.appendChild(topFragment);
|
||||
const visibleGameCount = elements.length;
|
||||
const hiddenCount = hiddenGames.length;
|
||||
const itemLabel = pageData.type === "a" ? "apps" : "games";
|
||||
document.getElementById("gameCount").innerText = hiddenCount > 0
|
||||
? `${visibleGameCount} games loaded (${hiddenCount} hidden)`
|
||||
: `${visibleGameCount} games loaded!`;
|
||||
? `${visibleGameCount} ${itemLabel} loaded (${hiddenCount} hidden)`
|
||||
: `${visibleGameCount} ${itemLabel} loaded!`;
|
||||
document.getElementById("loadingMsg").style.display = "none";
|
||||
document.getElementById("allHeader").style.display = "block";
|
||||
const topHeader = document.getElementById("topHeader");
|
||||
@ -134,6 +147,94 @@ async function loadGames() {
|
||||
e.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); starEvent(e); });
|
||||
});
|
||||
}
|
||||
|
||||
const recentHeader = document.getElementById("recentHeader");
|
||||
const recentGamesEl = document.getElementById("recentgames");
|
||||
if (recentHeader && recentGamesEl && localStorage.getItem("selenite.disableRecentlyPlayed") != "true") {
|
||||
const pageDirs = new Set(elements.map((el) => el.dataset.target));
|
||||
recentGames = getRecentlyPlayed().filter((dir) => !hiddenSet.has(dir) && pageDirs.has(dir));
|
||||
if (recentGames.length > 0) {
|
||||
recentHeader.style.display = "block";
|
||||
_rebuildRecent();
|
||||
}
|
||||
}
|
||||
|
||||
const tagSet = new Set();
|
||||
data.forEach((element) => {
|
||||
if (hiddenSet.has(element.directory)) return;
|
||||
(element.tags || []).forEach((t) => { if (t !== "top") tagSet.add(t); });
|
||||
});
|
||||
renderTagFilters([...tagSet].sort());
|
||||
}
|
||||
|
||||
function renderTagFilters(tags) {
|
||||
const chipsContainer = document.getElementById("tagChips");
|
||||
const chipsLabel = document.getElementById("tagChipsLabel");
|
||||
if (!chipsContainer) return;
|
||||
if (tags.length === 0) {
|
||||
chipsContainer.style.display = "none";
|
||||
if (chipsLabel) chipsLabel.style.display = "none";
|
||||
updateFiltersToggleLabel();
|
||||
return;
|
||||
}
|
||||
chipsContainer.innerHTML = "";
|
||||
const fragment = document.createDocumentFragment();
|
||||
tags.forEach((tag) => {
|
||||
const chip = document.createElement("button");
|
||||
chip.type = "button";
|
||||
chip.className = "tagChip";
|
||||
chip.innerText = tag;
|
||||
chip.dataset.tag = tag;
|
||||
chip.addEventListener("click", () => {
|
||||
if (selectedTags.has(tag)) {
|
||||
selectedTags.delete(tag);
|
||||
chip.classList.remove("active");
|
||||
} else {
|
||||
selectedTags.add(tag);
|
||||
chip.classList.add("active");
|
||||
}
|
||||
updateFiltersToggleLabel();
|
||||
applyFilters();
|
||||
});
|
||||
fragment.appendChild(chip);
|
||||
});
|
||||
chipsContainer.appendChild(fragment);
|
||||
updateFiltersToggleLabel();
|
||||
}
|
||||
|
||||
function updateFiltersToggleLabel() {
|
||||
const toggleBtn = document.getElementById("filtersToggle");
|
||||
if (!toggleBtn) return;
|
||||
toggleBtn.innerText = selectedTags.size > 0 ? `filters (${selectedTags.size})` : "filters";
|
||||
toggleBtn.classList.toggle("hasActive", selectedTags.size > 0);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const toggleBtn = document.getElementById("filtersToggle");
|
||||
const panel = document.getElementById("tagFilters");
|
||||
if (!toggleBtn || !panel) return;
|
||||
toggleBtn.addEventListener("click", () => {
|
||||
const isOpen = panel.classList.toggle("open");
|
||||
toggleBtn.classList.toggle("open", isOpen);
|
||||
});
|
||||
});
|
||||
|
||||
function applyFilters() {
|
||||
const searchInput = document.getElementById("gamesearch");
|
||||
const input = (searchInput ? searchInput.value : "").toUpperCase();
|
||||
let hidden = 0;
|
||||
elements.forEach((el) => {
|
||||
const matchesSearch = el.dataset.name.includes(input);
|
||||
const elTags = el.dataset.tags ? el.dataset.tags.split(",") : [];
|
||||
const matchesTags = selectedTags.size === 0 || elTags.some((t) => selectedTags.has(t));
|
||||
if (matchesSearch && matchesTags) {
|
||||
el.style.display = "flex";
|
||||
} else {
|
||||
el.style.display = "none";
|
||||
hidden++;
|
||||
}
|
||||
});
|
||||
document.getElementById("noResults").style.display = hidden >= elements.length ? "flex" : "none";
|
||||
}
|
||||
|
||||
let searchRaf = null;
|
||||
@ -141,17 +242,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
document.getElementById("gamesearch").addEventListener("input", () => {
|
||||
if (searchRaf) cancelAnimationFrame(searchRaf);
|
||||
searchRaf = requestAnimationFrame(() => {
|
||||
const input = document.getElementById("gamesearch").value.toUpperCase();
|
||||
let hidden = 0;
|
||||
elements.forEach((el) => {
|
||||
if (el.dataset.name.includes(input)) {
|
||||
el.style.display = "flex";
|
||||
} else {
|
||||
el.style.display = "none";
|
||||
hidden++;
|
||||
}
|
||||
});
|
||||
document.getElementById("noResults").style.display = hidden >= elements.length ? "flex" : "none";
|
||||
applyFilters();
|
||||
searchRaf = null;
|
||||
});
|
||||
});
|
||||
@ -160,15 +251,32 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
function _rebuildStarred() {
|
||||
const container = document.getElementById("starredgames");
|
||||
const gamesEl = document.getElementById("games");
|
||||
const topGEl = document.getElementById("topGames");
|
||||
container.innerHTML = "";
|
||||
const fragment = document.createDocumentFragment();
|
||||
starredGames.forEach((dir) => {
|
||||
const el = gamesEl.querySelector(`a.game[data-target='${dir}']`);
|
||||
const el = gamesEl.querySelector(`a.game[data-target='${dir}']`) || (topGEl && topGEl.querySelector(`a.game[data-target='${dir}']`));
|
||||
if (el) fragment.appendChild(el.cloneNode(true));
|
||||
});
|
||||
container.appendChild(fragment);
|
||||
}
|
||||
|
||||
function _rebuildRecent() {
|
||||
const container = document.getElementById("recentgames");
|
||||
const gamesEl = document.getElementById("games");
|
||||
const topGEl = document.getElementById("topGames");
|
||||
container.innerHTML = "";
|
||||
const fragment = document.createDocumentFragment();
|
||||
recentGames.slice(0, 4).forEach((dir) => {
|
||||
const el = gamesEl.querySelector(`a.game[data-target='${dir}']`) || (topGEl && topGEl.querySelector(`a.game[data-target='${dir}']`));
|
||||
if (el) fragment.appendChild(el.cloneNode(true));
|
||||
});
|
||||
container.appendChild(fragment);
|
||||
container.querySelectorAll("#star").forEach((e) => {
|
||||
e.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); starEvent(e); });
|
||||
});
|
||||
}
|
||||
|
||||
function getTotalPlayTime(directory) {
|
||||
const playTime = JSON.parse(localStorage.getItem("selenite.playTime") || "{}");
|
||||
return Object.values(playTime).reduce((total, day) => total + (day[directory] || 0), 0);
|
||||
@ -227,6 +335,18 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const randomBtn = document.getElementById("randomGame");
|
||||
if (!randomBtn) return;
|
||||
randomBtn.addEventListener("click", () => {
|
||||
if (elements.length === 0) return;
|
||||
const visible = elements.filter((el) => el.style.display !== "none");
|
||||
const pool = visible.length > 0 ? visible : elements;
|
||||
const random = pool[Math.floor(Math.random() * pool.length)];
|
||||
location.href = random.href;
|
||||
});
|
||||
});
|
||||
|
||||
function starEvent(e) {
|
||||
const game = e.target.parentNode.parentNode.getAttribute("data-target");
|
||||
starredGames = JSON.parse(localStorage.getItem("selenite.starred") || "[]");
|
||||
|
||||
Reference in New Issue
Block a user