function restoreCats(){ const openCats = JSON.parse(localStorage.getItem('openCats') || '[]'); openCats.forEach(id => { const el = document.getElementById(id); const btn = document.querySelector(`[onclick="toggleCat('${id}')"]`); if(el){ el.classList.add('open'); if(btn) btn.classList.add('open'); } }); } function goTo(categoryId) { if (!categoryId) return; var content = document.getElementById(categoryId); var button = document.querySelector("[onclick=\"toggleCat('" + categoryId + "')\"]"); if (content && !content.classList.contains('open')) { toggleCat(categoryId); setTimeout(function() { content.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 300); } else if (content) { content.scrollIntoView({ behavior: 'smooth', block: 'start' }); } document.getElementById('navSelect').value = ''; document.getElementById('gotonavSelect').value = ''; } function setLang(lang){ const t={ ru:{main:'Главная', mods:'Моды', combo:'Комбо', goto:'Перейти к', gotonav:'Перейти к', navcat1:'Коннекторы',navcat2:'Фиксы',navcat3:'Адаптации',navcat4:'Мёрджи / Восстановления',navcat5:'UI', gotonavcat1:'Коннекторы',gotonavcat2:'Фиксы',gotonavcat3:'Адаптации',gotonavcat4:'Мёрджи / Восстановления',gotonavcat5:'UI', title:'Моды от LyonzyiLeonid5', desc:'Здесь представлены моды, созданные Lyonzyi_Leonid5. Для того чтобы скачать выберите категорию в которой, находится мод, перейдите на страницу мода и намите "скачать".', cat1:'Коннекторы',cat2:'Фиксы',cat3:'Адаптации',cat4:'Мёрджи / Восстановления',cat5:'Пользвательский Интерфейс(UI)'}, en:{main:'Main', mods:'Mods', combo:'Combo', goto:'Go to ...', gotonav:'Go to ...', navcat1:'Connectors',navcat2:'Fixes',navcat3:'Adaptations',navcat4:'Merges / Restores',navcat5:'UI', gotonavcat1:'Connectors',gotonavcat2:'Fixes',gotonavcat3:'Adaptations',gotonavcat4:'Merges / Restores',gotonavcat5:'UI', title:'Mods by LyonzyiLeonid5', desc:'Here are mods created by Lyonzyi_Leonid5. To download, select the category the mod is in, go to the mods page, and click "Download".', cat1:'Connectors',cat2:'Fixes',cat3:'Adaptations',cat4:'Merges / Restores',cat5:'User Interface(UI)'} }; const headerTabs = document.querySelectorAll('.nav .tab'); if (headerTabs[0]) headerTabs[0].innerText = t[lang].main; if (headerTabs[1]) headerTabs[1].innerText = t[lang].mods; if (headerTabs[2]) headerTabs[2].innerText = t[lang].combo; const leftMain = document.querySelector('.left-panel #nav-main'); const leftMods = document.querySelector('.left-panel #nav-mods'); const leftCombo = document.querySelector('.left-panel #nav-combo'); if (leftMain) leftMain.innerText = t[lang].main; if (leftMods) leftMods.innerText = t[lang].mods; if (leftCombo) leftCombo.innerText = t[lang].combo; const rightMain = document.querySelector('.right-panel #nav-main'); const rightMods = document.querySelector('.right-panel #nav-mods'); const rightCombo = document.querySelector('.right-panel #nav-combo'); if (rightMain) rightMain.innerText = t[lang].main; if (rightMods) rightMods.innerText = t[lang].mods; if (rightCombo) rightCombo.innerText = t[lang].combo; document.getElementById('goto').innerText = t[lang].goto; document.getElementById('gotonav').innerText = t[lang].gotonav; document.getElementById('pageTitle').innerText = t[lang].title; document.getElementById('desc').innerText = t[lang].desc; document.getElementById('cat1').innerHTML = t[lang].cat1; document.getElementById('cat2').innerHTML = t[lang].cat2; document.getElementById('cat3').innerHTML = t[lang].cat3; document.getElementById('cat4').innerHTML = t[lang].cat4; document.getElementById('cat5').innerHTML = t[lang].cat5; localStorage.setItem('lang', lang); const navSelect = document.getElementById('navSelect'); if (navSelect) { navSelect.options[1].text = t[lang].navcat1; navSelect.options[2].text = t[lang].navcat2; navSelect.options[3].text = t[lang].navcat3; navSelect.options[4].text = t[lang].navcat4; navSelect.options[5].text = t[lang].navcat5; } const gotonavSelect = document.getElementById('gotonavSelect'); if (gotonavSelect) { gotonavSelect.options[1].text = t[lang].gotonavcat1; gotonavSelect.options[2].text = t[lang].gotonavcat2; gotonavSelect.options[3].text = t[lang].gotonavcat3; gotonavSelect.options[4].text = t[lang].gotonavcat4; gotonavSelect.options[5].text = t[lang].gotonavcat5; } syncLangSelects(); } function syncLangSelects() { const selects = document.querySelectorAll('#langSelect'); const currentLang = localStorage.getItem('lang') || 'ru'; selects.forEach(select => { if (select.value !== currentLang) { select.value = currentLang; } }); } // загрузка при старте const savedLang = localStorage.getItem('lang') || 'ru'; setLang(savedLang); syncLangSelects(); localStorage.setItem('lastPage', window.location.href); restoreCats(); /* ========================================================= SETTINGS ========================================================= */ const SCROLL_HIDE_POINT = 60; const SCROLL_SHOW_POINT = 60; const CATEGORY_STAGGER = 140; const CARD_STAGGER = 120; /* ========================================================= ELEMENTS ========================================================= */ const header = document.querySelector("header"); const leftPanel = document.querySelector(".left-panel"); const rightPanel = document.querySelector(".right-panel"); const categories = document.querySelectorAll(".category"); /* ========================================================= HEADER / SIDE PANEL ========================================================= */ const lang = document.querySelector(".lang"); window.addEventListener("scroll", () => { const scrollY = window.pageYOffset; // ===================================== // HIDE HEADER // ===================================== if (scrollY > SCROLL_HIDE_POINT) { header.classList.add("hide"); leftPanel.classList.add("show"); rightPanel.classList.add("show"); // lang move lang.classList.add("floating"); } // ===================================== // SHOW HEADER // ===================================== if (scrollY < SCROLL_SHOW_POINT) { header.classList.remove("hide"); leftPanel.classList.remove("show"); rightPanel.classList.remove("show"); // logo back logo.classList.remove("corner"); // lang back lang.classList.remove("floating"); } }); /* ========================================================= CATEGORY TOGGLE ========================================================= */ function toggleCat(id){ const content = document.getElementById(id); const button = document.querySelector( `[onclick="toggleCat('${id}')"]` ); const cards = content.querySelectorAll(".mod-card"); const isOpen = content.classList.contains("open"); // ===================================== // TOGGLE CATEGORY // ===================================== content.classList.toggle("open"); // rotate arrow button.classList.toggle("open", !isOpen); // ===================================== // SAVE OPENED TABS // ===================================== let openCats = JSON.parse( localStorage.getItem("openCats") || "[]" ); if (!isOpen) { if (!openCats.includes(id)) { openCats.push(id); } } else { openCats = openCats.filter(cat => cat !== id); } localStorage.setItem( "openCats", JSON.stringify(openCats) ); // ===================================== // CARD ANIMATION // ===================================== if (!isOpen) { cards.forEach((card, index) => { // reset before animation card.classList.remove("show"); setTimeout(() => { card.classList.add("show"); }, index * CARD_STAGGER); }); } else { cards.forEach(card => { card.classList.remove("show"); }); } } /* ========================================================= PAGE LOAD ========================================================= */ window.addEventListener("load", () => { // ===================================== // CATEGORY APPEAR // ===================================== categories.forEach((category, index) => { const button = category.querySelector(".cat-btn"); setTimeout(() => { // category fade category.classList.add("show"); // button expand if (button) { button.classList.add("show"); } }, index * CATEGORY_STAGGER); }); // ===================================== // RESTORE OPEN CATEGORIES // ===================================== const openCats = JSON.parse( localStorage.getItem("openCats") || "[]" ); openCats.forEach(id => { const content = document.getElementById(id); const button = document.querySelector( `[onclick="toggleCat('${id}')"]` ); if (!content) return; // restore open state content.classList.add("open"); if (button) { button.classList.add("open"); button.classList.add("show"); } // restore visible cards const cards = content.querySelectorAll(".mod-card"); cards.forEach((card, index) => { setTimeout(() => { card.classList.add("show"); }, index * CARD_STAGGER); }); }); }); // ===== ПЕРЕВОД ДЛЯ ПОИСКА ===== const searchTranslations = { ru: { searchPlaceholder: '🔍 Поиск модов...', totalLabel: 'Всего', foundLabel: 'Найдено', collapseAllLabel: 'Свернуть все', noResults: '🔍 Ничего не найдено. Попробуйте изменить запрос.', modsLabel: 'модов' }, en: { searchPlaceholder: '🔍 Search mods...', totalLabel: 'Total', foundLabel: 'Found', collapseAllLabel: 'Collapse all', noResults: '🔍 Nothing found. Please try another query.', modsLabel: 'mods' } }; // ===== ПОДСЧЁТ МОДОВ ===== function countMods() { const grids = document.querySelectorAll('.grid'); let total = 0; const lang = localStorage.getItem('lang') || 'ru'; const modsLabel = searchTranslations[lang]?.modsLabel || 'модов'; grids.forEach((grid, index) => { const cards = grid.querySelectorAll('.mod-card'); const count = cards.length; total += count; const countEl = document.getElementById(`cat${index + 1}Count`); if (countEl) { countEl.textContent = `${count} ${modsLabel}`; } }); document.getElementById('totalModsCount').textContent = total; document.getElementById('foundModsCount').textContent = total; } // ===== ОБНОВЛЕНИЕ ПЕРЕВОДОВ ПОИСКА ===== function updateSearchTranslations() { const lang = localStorage.getItem('lang') || 'ru'; const t = searchTranslations[lang] || searchTranslations.ru; const searchInput = document.getElementById('searchInput'); if (searchInput) searchInput.placeholder = t.searchPlaceholder; document.getElementById('totalLabel').textContent = t.totalLabel; document.getElementById('foundLabel').textContent = t.foundLabel; document.getElementById('collapseAllLabel').textContent = t.collapseAllLabel; document.getElementById('noResults').textContent = t.noResults; // Обновляем DevHub в навигации document.querySelectorAll('.nav .tab, .left-panel .tab, .right-panel .tab').forEach(tab => { if (tab.textContent === 'DevHub' || tab.id === 'nav-devhub' || tab.id === 'devhub') { tab.textContent = 'DevHub'; } }); } // ===== ПОИСК ===== function filterMods() { const query = document.getElementById('searchInput').value.toLowerCase().trim(); const allCards = document.querySelectorAll('.mod-card'); let found = 0; allCards.forEach(card => { const title = card.querySelector('.mod-title'); const text = title ? title.textContent.toLowerCase() : ''; if (query === '' || text.includes(query)) { card.classList.remove('hidden'); card.classList.add('filtered'); found++; } else { card.classList.add('hidden'); card.classList.remove('filtered'); } }); document.getElementById('foundModsCount').textContent = found; // Показываем/скрываем сообщение const noResults = document.getElementById('noResults'); if (query !== '' && found === 0) { noResults.classList.add('show'); } else { noResults.classList.remove('show'); } // Открываем категории, в которых есть найденные моды const categories = document.querySelectorAll('.category'); categories.forEach(cat => { const grid = cat.querySelector('.grid'); const visibleCards = grid ? grid.querySelectorAll('.mod-card:not(.hidden)') : []; const content = cat.querySelector('.cat-content'); const btn = cat.querySelector('.cat-btn'); if (visibleCards.length > 0 && query !== '') { if (content && !content.classList.contains('open')) { const id = content.id; toggleCat(id); } } }); } // ===== СВЕРНУТЬ ВСЕ ===== function collapseAll() { const openContents = document.querySelectorAll('.cat-content.open'); openContents.forEach(content => { const id = content.id; if (content.classList.contains('open')) { toggleCat(id); } }); document.getElementById('searchInput').value = ''; filterMods(); } // ===== ПЕРЕОПРЕДЕЛЯЕМ toggleCat ДЛЯ ПОДСЧЁТА ===== const originalToggleCat = window.toggleCat; window.toggleCat = function(id) { originalToggleCat(id); setTimeout(filterMods, 100); }; // ===== ПЕРЕОПРЕДЕЛЯЕМ setLang ДЛЯ ПЕРЕВОДА ПОИСКА ===== const originalSetLang = window.setLang; window.setLang = function(lang) { originalSetLang(lang); setTimeout(() => { countMods(); updateSearchTranslations(); }, 200); }; // ===== ИНИЦИАЛИЗАЦИЯ ===== document.addEventListener('DOMContentLoaded', function() { countMods(); updateSearchTranslations(); setTimeout(countMods, 500); });