/** * BlueSky MC Theme - main.js */ // ============================================= // MOBILE NAVBAR // ============================================= const navbar = document.querySelector('.navbar'); const hamburger = document.querySelector('.hamburger'); if (hamburger) { hamburger.addEventListener('click', () => { navbar.classList.toggle('active'); const links = navbar.querySelector('.links'); if (links) links.classList.toggle('active'); }); } // ============================================= // ACCORDION // ============================================= document.querySelectorAll('.accordion-item-header').forEach(header => { header.addEventListener('click', () => { header.classList.toggle('active'); const body = header.nextElementSibling; body.style.maxHeight = header.classList.contains('active') ? body.scrollHeight + 'px' : '0px'; }); }); // ============================================= // COPY IP // ============================================= const copyIpButton = document.querySelector('.copy-ip'); const copyIpAlert = document.querySelector('.ip-copied'); const serverIp = (typeof BlueSkyConfig !== 'undefined') ? BlueSkyConfig.serverIp : 'mc.example.com'; if (copyIpButton) { copyIpButton.addEventListener('click', () => { try { navigator.clipboard.writeText(serverIp); copyIpAlert.classList.add('active'); setTimeout(() => copyIpAlert.classList.remove('active'), 5000); } catch (e) { if (copyIpAlert) { copyIpAlert.textContent = 'Fehler beim Kopieren!'; copyIpAlert.classList.add('active', 'error'); setTimeout(() => { copyIpAlert.classList.remove('active','error'); copyIpAlert.textContent = 'War Erfolgreich!'; }, 5000); } } }); } // ============================================= // DISCORD ONLINE USERS // ============================================= const discordEl = document.querySelector('.discord-online-users'); if (discordEl && typeof BlueSkyConfig !== 'undefined' && BlueSkyConfig.discordServerId) { (async () => { try { const res = await fetch(`https://discord.com/api/guilds/${BlueSkyConfig.discordServerId}/widget.json`); const data = await res.json(); discordEl.textContent = data.presence_count || '0'; } catch { discordEl.textContent = '0'; } })(); } // ============================================= // MINECRAFT ONLINE PLAYERS // ============================================= const mcEl = document.querySelector('.minecraft-online-players'); if (mcEl && typeof BlueSkyConfig !== 'undefined' && BlueSkyConfig.serverIp) { (async () => { try { const res = await fetch(`https://api.mcsrvstat.us/3/${BlueSkyConfig.serverIp}`); const data = await res.json(); mcEl.textContent = data?.players?.online ?? '0'; } catch { mcEl.textContent = '0'; } })(); } // ============================================= // UUID LOOKUP — mehrere APIs als Fallback // ============================================= async function getUUID(username) { // API 1: Mojang direkt try { const res = await fetch(`https://api.mojang.com/users/profiles/minecraft/${username}`); if (res.ok) { const data = await res.json(); if (data?.id) return data.id; } } catch {} // API 2: PlayerDB try { const res = await fetch(`https://playerdb.co/api/player/minecraft/${username}`); if (res.ok) { const data = await res.json(); if (data?.data?.player?.raw_id) return data.data.player.raw_id; } } catch {} // API 3: MCHeads try { const res = await fetch(`https://mc-heads.net/minecraft/profile/${username}`); if (res.ok) { const data = await res.json(); if (data?.id) return data.id; } } catch {} return null; } // ============================================= // TEAM MEMBER SKINS // ============================================= const memberSkins = document.querySelectorAll('.member-skin'); if (memberSkins.length > 0) { const skinType = (typeof BlueSkyConfig !== 'undefined') ? BlueSkyConfig.skinType : 'bust'; memberSkins.forEach(async (img) => { const memberDiv = img.closest('.user'); if (!memberDiv) return; const customSkin = memberDiv.dataset.skin; // Eigene URL gesetzt → direkt verwenden if (customSkin && customSkin.trim().length > 0) { img.src = customSkin; return; } const inGameName = memberDiv.dataset.ingame; if (!inGameName) return; // Lade-Platzhalter img.style.opacity = '0.4'; img.style.filter = 'grayscale(1)'; try { const uuid = await getUUID(inGameName); if (uuid) { // visage.surgeplay.com für hohe Qualität const skinUrl = `https://visage.surgeplay.com/${skinType}/256/${uuid}`; img.src = skinUrl; img.onload = () => { img.style.opacity = '1'; img.style.filter = 'none'; }; img.onerror = () => { // Fallback: crafthead img.src = `https://crafthead.net/${skinType === 'bust' ? 'bust' : skinType === 'head' ? 'avatar' : 'body'}/${uuid}/256`; img.style.opacity = '1'; img.style.filter = 'none'; }; } else { // Kein UUID gefunden → crafthead direkt mit Username img.src = `https://crafthead.net/bust/${inGameName}/256`; img.style.opacity = '1'; img.style.filter = 'none'; } } catch (e) { img.src = `https://crafthead.net/bust/${inGameName}/256`; img.style.opacity = '1'; img.style.filter = 'none'; console.warn('Skin load error for', inGameName, e); } }); } // ============================================= // SMOOTH SCROLL // ============================================= document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function(e) { const target = document.querySelector(this.getAttribute('href')); if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth' }); } }); }); // ============================================= // WIKI SIDEBAR TOGGLE // ============================================= (function initWikiSidebarToggle() { const categories = document.querySelectorAll('.wiki-nav-cat'); if (!categories.length) return; const updateCategory = (cat, isOpen) => { const header = cat.querySelector('.wiki-nav-cat-header'); const body = cat.querySelector('.wiki-nav-cat-body'); if (!header || !body) return; cat.classList.toggle('open', isOpen); header.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); body.style.maxHeight = isOpen ? body.scrollHeight + 'px' : '0px'; }; categories.forEach((cat, index) => { const header = cat.querySelector('.wiki-nav-cat-header'); const body = cat.querySelector('.wiki-nav-cat-body'); if (!header || !body) return; const bodyId = `wiki-nav-body-${index + 1}`; body.id = bodyId; header.setAttribute('role', 'button'); header.setAttribute('tabindex', '0'); header.setAttribute('aria-controls', bodyId); const initiallyOpen = cat.classList.contains('open'); updateCategory(cat, initiallyOpen); header.addEventListener('click', () => { const isOpen = !cat.classList.contains('open'); updateCategory(cat, isOpen); }); header.addEventListener('keydown', (event) => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); const isOpen = !cat.classList.contains('open'); updateCategory(cat, isOpen); } }); }); window.addEventListener('resize', () => { categories.forEach((cat) => { if (!cat.classList.contains('open')) return; const body = cat.querySelector('.wiki-nav-cat-body'); if (!body) return; body.style.maxHeight = body.scrollHeight + 'px'; }); }); })(); // ============================================= // WIKI ARTICLE ANSWER ACCORDION // ============================================= (function initWikiAnswerAccordion() { const accordions = document.querySelectorAll('[data-wiki-answer]'); if (!accordions.length) return; const setOpenState = (accordion, open) => { const toggle = accordion.querySelector('.wiki-answer-toggle'); const panel = accordion.querySelector('.wiki-answer-panel'); if (!toggle || !panel) return; accordion.classList.toggle('is-open', open); toggle.setAttribute('aria-expanded', open ? 'true' : 'false'); panel.style.maxHeight = open ? panel.scrollHeight + 'px' : '0px'; }; accordions.forEach((accordion) => { const toggle = accordion.querySelector('.wiki-answer-toggle'); if (!toggle) return; setOpenState(accordion, false); toggle.addEventListener('click', () => { const shouldOpen = !accordion.classList.contains('is-open'); setOpenState(accordion, shouldOpen); }); }); window.addEventListener('resize', () => { accordions.forEach((accordion) => { if (!accordion.classList.contains('is-open')) return; const panel = accordion.querySelector('.wiki-answer-panel'); if (!panel) return; panel.style.maxHeight = panel.scrollHeight + 'px'; }); }); })(); // ============================================= // RULES ACCORDION // ============================================= (function initRulesAccordion() { const cards = document.querySelectorAll('.rule-card'); if (!cards.length) return; const setOpenState = (card, open) => { const toggle = card.querySelector('.rule-toggle'); const panel = card.querySelector('.rule-content-panel'); if (!toggle || !panel) return; card.classList.toggle('is-open', open); toggle.setAttribute('aria-expanded', open ? 'true' : 'false'); panel.style.maxHeight = open ? panel.scrollHeight + 'px' : '0px'; }; cards.forEach((card) => { const toggle = card.querySelector('.rule-toggle'); if (!toggle) return; setOpenState(card, false); toggle.addEventListener('click', () => { const shouldOpen = !card.classList.contains('is-open'); cards.forEach((otherCard) => { if (otherCard !== card) setOpenState(otherCard, false); }); setOpenState(card, shouldOpen); }); }); window.addEventListener('resize', () => { cards.forEach((card) => { if (!card.classList.contains('is-open')) return; const panel = card.querySelector('.rule-content-panel'); if (!panel) return; panel.style.maxHeight = panel.scrollHeight + 'px'; }); }); })(); // ============================================= // WIKI OVERVIEW TABS // ============================================= (function initWikiOverviewTabs() { const tabButtons = document.querySelectorAll('.wiki-tab-button'); const tabPanels = document.querySelectorAll('.wiki-tab-panel'); if (!tabButtons.length || !tabPanels.length) return; tabButtons.forEach((button) => { button.addEventListener('click', () => { const targetId = button.getAttribute('data-tab'); if (!targetId) return; tabButtons.forEach((btn) => btn.classList.remove('active')); tabPanels.forEach((panel) => panel.classList.remove('active')); button.classList.add('active'); const targetPanel = document.getElementById(targetId); if (targetPanel) targetPanel.classList.add('active'); }); }); })();