diff --git a/equipment/equipment.js b/equipment/equipment.js index 6ee542e..f3bc3bc 100644 --- a/equipment/equipment.js +++ b/equipment/equipment.js @@ -1,4 +1,4 @@ -window.loadHeader(function(headerContainer) { +window.loadHeader(async function(headerContainer) { const logoutForm = document.getElementById("logout-form"); if (logoutForm) { logoutForm.action = "/api/v1/spfn/logout"; @@ -41,6 +41,7 @@ window.loadHeader(function(headerContainer) { }; let combinedData = {}; + let mappingCache = null; const preloadImage = (url) => { return new Promise((resolve) => { @@ -52,7 +53,7 @@ window.loadHeader(function(headerContainer) { }); }; - const renderData = async (newData) => { + const renderData = async (newData, isFinalFallback = false) => { if (!newData) return; let data = newData; @@ -85,20 +86,25 @@ window.loadHeader(function(headerContainer) { const infoBox = document.querySelector('.splat-info-box'); if (infoBox) { - const fetchJson = url => fetch(url).then(r => r.ok ? r.json() : []); - const [clothing, headgear, shoes, weapons, abilities] = await Promise.all([ - fetchJson('/assets/mapping/clothing.json'), - fetchJson('/assets/mapping/headgear.json'), - fetchJson('/assets/mapping/shoes.json'), - fetchJson('/assets/mapping/weapons.json'), - fetchJson('/assets/mapping/ability.json') - ]); + if (!mappingCache) { + const fetchJson = url => fetch(url).then(r => r.ok ? r.json() : []); + mappingCache = await Promise.all([ + fetchJson('/assets/mapping/clothing.json'), + fetchJson('/assets/mapping/headgear.json'), + fetchJson('/assets/mapping/shoes.json'), + fetchJson('/assets/mapping/weapons.json'), + fetchJson('/assets/mapping/ability.json') + ]); + } + const [clothing, headgear, shoes, weapons, abilities] = mappingCache; const getImg = (list, id, folder, isAbility = false) => { - const fallback = isAbility ? "../assets/ability/ParameterIcon^q.png" : "/assets/weapons/NotFound^w.png"; - if (id === undefined || id === null) return fallback; + if (id === undefined || id === null) { + return isFinalFallback ? (isAbility ? "../assets/ability/ParameterIcon^q.png" : "/assets/weapons/NotFound^w.png") : ""; + } const item = list.find(i => String(i.id) === String(id)); - return (item && item.image) ? `../assets/${folder}/${item.image}` : fallback; + if (item && item.image) return `../assets/${folder}/${item.image}`; + return isFinalFallback ? (isAbility ? "../assets/ability/ParameterIcon^q.png" : "/assets/weapons/NotFound^w.png") : ""; }; const weaponImg = getImg(weapons, equipped.weapon, 'weapons'); @@ -131,7 +137,10 @@ window.loadHeader(function(headerContainer) { const rankLevel = equipped.Rank !== undefined ? equipped.Rank : (finalData.Rank || "--"); const udemaeKey = equipped.Udemae !== undefined ? String(equipped.Udemae) : String(finalData.Udemae || ""); - const rankGrade = udemaeMap[udemaeKey] || (udemaeKey !== "undefined" && udemaeKey !== "" ? udemaeKey : "C-"); + const rankGrade = udemaeMap[udemaeKey] || (udemaeKey !== "undefined" && udemaeKey !== "" ? udemaeKey : "--"); + + const renderImg = (src, className) => src ? `` : ''; + const renderSub = (src) => src ? `` : ''; infoBox.innerHTML = `
@@ -149,30 +158,30 @@ window.loadHeader(function(headerContainer) { ${rankGrade}
-
+
${renderImg(weaponImg, 'weapon')}
- - + ${renderImg(headMain, 'main-ability')} + ${renderImg(headImg, 'gear-icon')}
- + ${renderSub(clothesSub1)}${renderSub(clothesSub2)}${renderSub(clothesSub3)}
- - + ${renderImg(clothesMain, 'main-ability')} + ${renderImg(clothesImg, 'gear-icon')}
- + ${renderSub(headSub1)}${renderSub(headSub2)}${renderSub(headSub3)}
- - + ${renderImg(shoesMain, 'main-ability')} + ${renderImg(shoesImg, 'gear-icon')}
- + ${renderSub(shoesSub1)}${renderSub(shoesSub2)}${renderSub(shoesSub3)}
@@ -185,18 +194,32 @@ window.loadHeader(function(headerContainer) { const init = async () => { const overlay = document.getElementById("loading-overlay"); + let cacheFound = false; + + const cached = sessionStorage.getItem('user_cache'); + if (cached) { + try { + await renderData(JSON.parse(cached), false); + cacheFound = true; + } catch (e) {} + } + try { const [profileRes, equipRes] = await Promise.all([ fetch("/api/v1/me", { credentials: 'include' }).then(res => res.ok ? res.json() : {}), fetch("/api/v1/me/equipment", { credentials: 'include' }).then(res => res.ok ? res.json() : {}) ]); - await renderData(profileRes); - await renderData(equipRes); + + await renderData(profileRes, false); + await renderData(equipRes, false); sessionStorage.setItem('user_cache', JSON.stringify(combinedData)); } catch (err) { - const cached = sessionStorage.getItem('user_cache'); - if (cached) await renderData(JSON.parse(cached)); - else await renderData({ user_id: "Guest" }); + //last resort + if (cacheFound) { + await renderData(sessionStorage.getItem('user_cache'), true); + } else { + await renderData({ user_id: "Guest" }, true); + } } finally { if (overlay) overlay.style.display = "none"; } diff --git a/stages/stages.js b/stages/stages.js index 426e6fd..8cc7d8c 100644 --- a/stages/stages.js +++ b/stages/stages.js @@ -3,19 +3,17 @@ let currentIndex = 0; const ITEMS_PER_PAGE = 5; let observer; -window.loadHeader(function(headerContainer) { +window.loadHeader(async function(headerContainer) { const stageButton = headerContainer.querySelector('.menu-item.stage'); if (stageButton) { stageButton.classList.add('active'); } const logoutForm = document.getElementById("logout-form"); - if (logoutForm) { logoutForm.action = "/api/v1/spfn/logout"; const originInput = document.getElementById("logout_frontend_origin"); if (originInput) originInput.value = window.location.origin; - logoutForm.addEventListener('submit', () => { sessionStorage.removeItem('user_cache'); }); @@ -47,7 +45,8 @@ window.loadHeader(function(headerContainer) { } }; - const renderData = (data) => { + const renderData = async (data) => { + if (!data) return; if (typeof data === 'string') { try { data = JSON.parse(data); } catch (e) { console.error(e); } } @@ -66,24 +65,38 @@ window.loadHeader(function(headerContainer) { } }; - const cached = sessionStorage.getItem('user_cache'); - if (cached) renderData(JSON.parse(cached)); + const init = async () => { + const overlay = document.getElementById("loading-overlay"); + let cacheReady = false; - fetch("/api/v1/me", { credentials: 'include' }) - .then(res => res.ok ? res.json() : Promise.reject(res)) - .then(data => { - sessionStorage.setItem('user_cache', JSON.stringify(data)); - renderData(data); - }) - .catch(err => { - if (!cached) { + const cached = sessionStorage.getItem('user_cache'); + if (cached) { + try { + await renderData(cached); + cacheReady = true; + } catch (e) {} + } + + try { + const [profileRes, rotationsData] = await Promise.all([ + fetch("/api/v1/me", { credentials: 'include' }).then(res => res.ok ? res.json() : {}), + renderStages() + ]); + + await renderData(profileRes); + sessionStorage.setItem('user_cache', JSON.stringify(profileRes)); + } catch (err) { + if (!cacheReady) { const nameEl = document.getElementById('mii-name'); if (nameEl) nameEl.textContent = "Guest"; } console.error(err); - }); + } finally { + if (overlay) overlay.style.display = "none"; + } + }; - renderStages(); + init(); }); const API_URL = "/api/v1/boss"; @@ -144,13 +157,11 @@ async function fetchRotations() { async function renderStages() { const container = document.getElementById("stages-container"); - const loadingOverlay = document.getElementById("loading-overlay"); try { allRotations = await fetchRotations(); if (!allRotations.length) { container.innerHTML = `

Something went wrong! Try reloading the page.

`; - if (loadingOverlay) loadingOverlay.style.display = 'none'; return; } @@ -174,7 +185,6 @@ async function renderStages() { } catch (err) { console.error(err); - if (loadingOverlay) loadingOverlay.style.display = 'none'; } } @@ -183,7 +193,7 @@ function loadMore(isInitial) { const loadingOverlay = document.getElementById("loading-overlay"); const trigger = document.getElementById('scroll-trigger'); - if (loadingOverlay) { + if (!isInitial && loadingOverlay) { loadingOverlay.style.display = 'flex'; if (typeof window.animateLoadingCanvas === 'function') { window.animateLoadingCanvas(); @@ -254,7 +264,7 @@ function loadMore(isInitial) { container.insertAdjacentHTML('beforeend', html); currentIndex += ITEMS_PER_PAGE; - if (loadingOverlay) loadingOverlay.style.display = 'none'; + if (!isInitial && loadingOverlay) loadingOverlay.style.display = 'none'; if (trigger) trigger.style.display = 'block'; if (currentIndex >= allRotations.length) {