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);
});