document.addEventListener('DOMContentLoaded', function () { const container = document.getElementById('starterkit-container'); const shuffleContainers = document.querySelectorAll('.shuffle-container'); const seed = Date.now(); // Lade die Haupt-Konfigurationsdatei fetch('config.json') .then(response => response.json()) .then(config => { const starterkitFiles = config.starterkits; // Lade alle StarterKit-Dateien return Promise.all( starterkitFiles.map(file => fetch(file).then(res => res.json())) ); }) .then(starterkits => { // Verarbeite die geladenen StarterKits starterkits.forEach(kit => { const kitElement = createStarterKitElement(kit); container.appendChild(kitElement); }); // Shuffle-Logik anwenden shuffleContainers.forEach(container => { seededShuffleChildren(container, seed); }); // Zusätzliche Funktionalität für StarterKits hinzufügen enhanceStarterKits(); }) .catch(error => console.error('Fehler beim Laden der StarterKits:', error)); }); /** * Erstellt das HTML für ein StarterKit */ function createStarterKitElement(kit) { const kitElement = document.createElement('div'); kitElement.classList.add('starterkit'); const title = document.createElement('h3'); title.textContent = kit.name; const description = document.createElement('p'); description.textContent = kit.description; const authorContainer = document.createElement('div'); authorContainer.classList.add('autor'); const authorLink = document.createElement('a'); authorLink.classList.add('account'); authorLink.href = kit.author; authorLink.target = '_blank'; fetchAuthorProfile(kit.author, authorLink); authorContainer.textContent = 'zusammengestellt von '; authorContainer.appendChild(authorLink); kitElement.appendChild(title); kitElement.appendChild(description); kitElement.appendChild(authorContainer); const accountCountElement = document.createElement('div'); accountCountElement.classList.add('account-count'); accountCountElement.textContent = `${kit.accounts.length} Profile`; kitElement.appendChild(accountCountElement); // Speichere die Accounts in einem Dataset für späteres Laden kitElement.dataset.accounts = JSON.stringify(kit.accounts); return kitElement; } /** * Ruft den Avatar und andere Informationen für den Autor ab und fügt sie hinzu */ function fetchAuthorProfile(authorUrl, linkElement) { try { const url = new URL(authorUrl); const pathParts = url.pathname.split('/'); if (pathParts.length > 1 && pathParts[1].startsWith('@')) { const handle = pathParts[1].substring(1); const instance = url.hostname; const lookupUrl = `https://${instance}/api/v1/accounts/lookup?acct=${handle}`; fetch(lookupUrl) .then(response => response.json()) .then(data => { linkElement.textContent = data.display_name || data.username; const avatarImage = document.createElement('img'); avatarImage.classList.add('account-avatar'); avatarImage.alt = data.avatar ? `Profilbild von ${data.username}` : 'Profilbild nicht verfügbar'; avatarImage.src = data.avatar || ''; linkElement.prepend(avatarImage); const serverClass = getServerClass(instance); if (serverClass) { linkElement.classList.add(serverClass); } }) .catch(error => console.error(`Fehler beim Abrufen des Profils für ${authorUrl}:`, error)); } } catch (error) { console.error('Ungültige URL:', authorUrl, error); } } /** * Zusätzliche Funktionen für StarterKits */ function enhanceStarterKits() { const starterkits = document.querySelectorAll('.starterkit'); starterkits.forEach(kit => { kit.addEventListener('click', function () { const title = kit.querySelector('h3').textContent; const accounts = JSON.parse(kit.dataset.accounts || '[]'); const popup = createRecommendationPopup(accounts, title); document.body.appendChild(popup); }); }); } /** * Erstellt ein Pop-up für die Account-Empfehlungen */ function createRecommendationPopup(accounts, title) { const overlay = document.createElement('div'); overlay.classList.add('recommendation-popup'); const content = document.createElement('div'); content.classList.add('recommendation-popup-content'); const header = document.createElement('div'); header.classList.add('recommendation-popup-header'); const titleElement = document.createElement('h3'); titleElement.textContent = title; const closeButton = document.createElement('button'); closeButton.classList.add('close-popup'); closeButton.textContent = '×'; closeButton.addEventListener('click', () => overlay.remove()); header.appendChild(titleElement); header.appendChild(closeButton); const body = document.createElement('div'); body.classList.add('recommendation-popup-body'); accounts.forEach(accountUrl => { const accountLink = document.createElement('a'); accountLink.classList.add('account'); accountLink.href = accountUrl; accountLink.target = '_blank'; // Lade Profilinformationen für das Konto fetchAccountProfile(accountUrl, accountLink) .then(card => body.appendChild(card)); }); content.appendChild(header); content.appendChild(body); overlay.appendChild(content); overlay.addEventListener('click', function (event) { if (event.target === overlay) { overlay.remove(); } }); return overlay; } /** * Ruft Profilinformationen ab und erstellt eine Profil-Kachel */ function fetchAccountProfile(accountUrl, linkElement) { return new Promise((resolve, reject) => { try { const url = new URL(accountUrl); const pathParts = url.pathname.split('/'); if (pathParts.length > 1 && pathParts[1].startsWith('@')) { const handle = pathParts[1].substring(1); const instance = url.hostname; const lookupUrl = `https://${instance}/api/v1/accounts/lookup?acct=${handle}`; fetch(lookupUrl) .then(response => response.json()) .then(data => { const card = createAccountCard(data, accountUrl, instance); resolve(card); }) .catch(error => { console.error(`Fehler beim Abrufen des Profils für ${accountUrl}:`, error); reject(error); }); } } catch (error) { console.error('Ungültige URL:', accountUrl, error); reject(error); } }); } /** * Erstellt eine Account-Kachel */ function createAccountCard(data, href, instance) { const link = document.createElement('a'); link.classList.add('account-card-link'); link.href = href; link.target = '_blank'; const card = document.createElement('div'); card.classList.add('account-card'); const avatarImage = document.createElement('img'); avatarImage.classList.add('account-avatar'); avatarImage.alt = data.avatar ? `Profilbild von ${data.username}` : 'Profilbild nicht verfügbar'; avatarImage.src = data.avatar || ''; const infoContainer = document.createElement('div'); infoContainer.classList.add('account-info'); const displayNameElement = document.createElement('p'); displayNameElement.classList.add('display-name'); displayNameElement.textContent = data.display_name || data.username; const handleElement = document.createElement('p'); handleElement.classList.add('handle'); const serverHandleElement = document.createElement('span'); serverHandleElement.classList.add('server-handle'); serverHandleElement.textContent = `@${instance}`; serverHandleElement.style.backgroundColor = getServerClass(instance); handleElement.textContent = `@${data.username}`; handleElement.appendChild(serverHandleElement); infoContainer.appendChild(displayNameElement); infoContainer.appendChild(handleElement); card.appendChild(avatarImage); card.appendChild(infoContainer); link.appendChild(card); return link; } /** * Deterministisch Kinder neu anordnen */ function seededShuffleChildren(container, seed) { const children = Array.from(container.children); const shuffled = seededShuffle(children, seed); shuffled.forEach(child => container.appendChild(child)); } function seededShuffle(array, seed) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(seededRandom(seed++) * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } function seededRandom(seed) { const x = Math.sin(seed++) * 10000; return x - Math.floor(x); } function getServerClass(instance) { const serverClasses = { 'libori.social': 'rgb(255, 86, 86)', 'reliverse.social': 'rgb(255, 165, 0)', 'kirche.social': 'rgb(28, 125, 126)', 'katholisch.social': 'rgb(14, 123, 226)' }; return serverClasses[instance] || 'rgb(69, 89, 109)'; } /** * Extrahiert den Handle (z. B. @benutzer@instanz) aus einer URL */ function extractHandleFromURL(url) { try { const parsedUrl = new URL(url); const pathParts = parsedUrl.pathname.split('/'); return pathParts.length > 1 ? pathParts[1] : url; } catch (error) { console.error('Ungültige URL:', url); return url; } }