2024-12-09 22:53:00 +01:00
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
|
const container = document.getElementById('starterkit-container');
|
2024-12-08 22:48:40 +01:00
|
|
|
|
const shuffleContainers = document.querySelectorAll('.shuffle-container');
|
|
|
|
|
const seed = Date.now();
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
// 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));
|
|
|
|
|
});
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
/**
|
|
|
|
|
* Erstellt das HTML für ein StarterKit
|
|
|
|
|
*/
|
|
|
|
|
function createStarterKitElement(kit) {
|
|
|
|
|
const kitElement = document.createElement('div');
|
|
|
|
|
kitElement.classList.add('starterkit');
|
2024-12-08 22:48:40 +01:00
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
const title = document.createElement('h3');
|
|
|
|
|
title.textContent = kit.name;
|
2024-12-08 22:48:40 +01:00
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
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';
|
|
|
|
|
|
2024-12-09 23:06:48 +01:00
|
|
|
|
fetchProfile(kit.author, { updateElement: authorLink });
|
2024-12-09 22:53:00 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Zusätzliche Funktionen für StarterKits
|
|
|
|
|
*/
|
|
|
|
|
function enhanceStarterKits() {
|
|
|
|
|
const starterkits = document.querySelectorAll('.starterkit');
|
2024-12-08 22:48:40 +01:00
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
starterkits.forEach(kit => {
|
|
|
|
|
kit.addEventListener('click', function () {
|
2024-12-08 22:48:40 +01:00
|
|
|
|
const title = kit.querySelector('h3').textContent;
|
2024-12-09 22:53:00 +01:00
|
|
|
|
const accounts = JSON.parse(kit.dataset.accounts || '[]');
|
|
|
|
|
const popup = createRecommendationPopup(accounts, title);
|
2024-12-08 22:48:40 +01:00
|
|
|
|
document.body.appendChild(popup);
|
|
|
|
|
});
|
|
|
|
|
});
|
2024-12-09 22:53:00 +01:00
|
|
|
|
}
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
/**
|
2024-12-09 22:53:00 +01:00
|
|
|
|
* Erstellt ein Pop-up für die Account-Empfehlungen
|
2024-12-08 22:48:40 +01:00
|
|
|
|
*/
|
|
|
|
|
function createRecommendationPopup(accounts, title) {
|
|
|
|
|
const overlay = document.createElement('div');
|
|
|
|
|
overlay.classList.add('recommendation-popup');
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
const content = document.createElement('div');
|
|
|
|
|
content.classList.add('recommendation-popup-content');
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
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 = '×';
|
2024-12-09 22:53:00 +01:00
|
|
|
|
closeButton.addEventListener('click', () => overlay.remove());
|
2024-12-08 22:48:40 +01:00
|
|
|
|
|
|
|
|
|
header.appendChild(titleElement);
|
|
|
|
|
header.appendChild(closeButton);
|
|
|
|
|
|
|
|
|
|
const body = document.createElement('div');
|
|
|
|
|
body.classList.add('recommendation-popup-body');
|
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
accounts.forEach(accountUrl => {
|
2024-12-09 23:06:48 +01:00
|
|
|
|
fetchProfile(accountUrl, { createCard: true })
|
|
|
|
|
.then(card => body.appendChild(card))
|
|
|
|
|
.catch(error => console.error(`Fehler beim Laden des Accounts: ${accountUrl}`, error));
|
2024-12-09 22:53:00 +01:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
content.appendChild(header);
|
|
|
|
|
content.appendChild(body);
|
|
|
|
|
overlay.appendChild(content);
|
|
|
|
|
|
|
|
|
|
overlay.addEventListener('click', function (event) {
|
|
|
|
|
if (event.target === overlay) {
|
|
|
|
|
overlay.remove();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return overlay;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-12-09 23:06:48 +01:00
|
|
|
|
* Ruft Profilinformationen ab und aktualisiert ein DOM-Element oder erstellt eine Profil-Kachel.
|
2024-12-09 22:53:00 +01:00
|
|
|
|
*/
|
2024-12-09 23:06:48 +01:00
|
|
|
|
function fetchProfile(profileUrl, options = {}) {
|
|
|
|
|
const { updateElement = null, createCard = false } = options;
|
|
|
|
|
|
2024-12-09 22:53:00 +01:00
|
|
|
|
return new Promise((resolve, reject) => {
|
2024-12-08 08:58:41 +01:00
|
|
|
|
try {
|
2024-12-09 23:06:48 +01:00
|
|
|
|
const url = new URL(profileUrl);
|
2024-12-08 08:58:41 +01:00
|
|
|
|
const pathParts = url.pathname.split('/');
|
|
|
|
|
if (pathParts.length > 1 && pathParts[1].startsWith('@')) {
|
|
|
|
|
const handle = pathParts[1].substring(1);
|
|
|
|
|
const instance = url.hostname;
|
2024-12-09 22:53:00 +01:00
|
|
|
|
const lookupUrl = `https://${instance}/api/v1/accounts/lookup?acct=${handle}`;
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
|
|
|
|
fetch(lookupUrl)
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
2024-12-09 23:06:48 +01:00
|
|
|
|
if (updateElement) {
|
|
|
|
|
// Aktualisiere das übergebene Element
|
|
|
|
|
updateElement.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 || '';
|
|
|
|
|
updateElement.prepend(avatarImage);
|
|
|
|
|
|
|
|
|
|
const serverClass = getServerClass(instance);
|
|
|
|
|
if (serverClass) {
|
|
|
|
|
updateElement.classList.add(serverClass);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resolve(updateElement);
|
|
|
|
|
} else if (createCard) {
|
|
|
|
|
// Erstelle eine Profil-Kachel
|
|
|
|
|
const card = createAccountCard(data, profileUrl, instance);
|
|
|
|
|
resolve(card);
|
|
|
|
|
}
|
2024-12-08 08:58:41 +01:00
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
2024-12-09 23:06:48 +01:00
|
|
|
|
console.error(`Fehler beim Abrufen des Profils für ${profileUrl}:`, error);
|
2024-12-09 22:53:00 +01:00
|
|
|
|
reject(error);
|
2024-12-08 08:58:41 +01:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-12-09 23:06:48 +01:00
|
|
|
|
console.error('Ungültige URL:', profileUrl, error);
|
2024-12-09 22:53:00 +01:00
|
|
|
|
reject(error);
|
2024-12-08 08:58:41 +01:00
|
|
|
|
}
|
|
|
|
|
});
|
2024-12-08 22:48:40 +01:00
|
|
|
|
}
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
/**
|
2024-12-09 22:53:00 +01:00
|
|
|
|
* Erstellt eine Account-Kachel
|
2024-12-08 22:48:40 +01:00
|
|
|
|
*/
|
|
|
|
|
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}`;
|
2024-12-09 23:06:48 +01:00
|
|
|
|
|
|
|
|
|
// Ergänze die Klasse basierend auf der Instanz
|
|
|
|
|
const serverClass = getServerClass(instance);
|
|
|
|
|
if (serverClass) {
|
|
|
|
|
serverHandleElement.classList.add(serverClass);
|
|
|
|
|
}
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
handleElement.textContent = `@${data.username}`;
|
|
|
|
|
handleElement.appendChild(serverHandleElement);
|
|
|
|
|
|
|
|
|
|
infoContainer.appendChild(displayNameElement);
|
|
|
|
|
infoContainer.appendChild(handleElement);
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
card.appendChild(avatarImage);
|
|
|
|
|
card.appendChild(infoContainer);
|
|
|
|
|
link.appendChild(card);
|
2024-12-08 08:58:41 +01:00
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
return link;
|
2024-12-08 08:58:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-08 22:48:40 +01:00
|
|
|
|
/**
|
2024-12-09 22:53:00 +01:00
|
|
|
|
* Deterministisch Kinder neu anordnen
|
2024-12-08 22:48:40 +01:00
|
|
|
|
*/
|
|
|
|
|
function seededShuffleChildren(container, seed) {
|
|
|
|
|
const children = Array.from(container.children);
|
|
|
|
|
const shuffled = seededShuffle(children, seed);
|
|
|
|
|
shuffled.forEach(child => container.appendChild(child));
|
2024-12-08 08:58:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function seededShuffle(array, seed) {
|
|
|
|
|
for (let i = array.length - 1; i > 0; i--) {
|
2024-12-08 22:48:40 +01:00
|
|
|
|
const j = Math.floor(seededRandom(seed++) * (i + 1));
|
2024-12-08 08:58:41 +01:00
|
|
|
|
[array[i], array[j]] = [array[j], array[i]];
|
|
|
|
|
}
|
|
|
|
|
return array;
|
|
|
|
|
}
|
2024-12-08 22:48:40 +01:00
|
|
|
|
|
|
|
|
|
function seededRandom(seed) {
|
|
|
|
|
const x = Math.sin(seed++) * 10000;
|
|
|
|
|
return x - Math.floor(x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getServerClass(instance) {
|
|
|
|
|
const serverClasses = {
|
2024-12-09 23:06:48 +01:00
|
|
|
|
'libori.social': 'liboriSocial',
|
|
|
|
|
'reliverse.social': 'reliverseSocial',
|
|
|
|
|
'kirche.social': 'kircheSocial',
|
|
|
|
|
'katholisch.social': 'katholischSocial'
|
2024-12-08 22:48:40 +01:00
|
|
|
|
};
|
2024-12-09 23:06:48 +01:00
|
|
|
|
return serverClasses[instance] || null;
|
2024-12-09 22:53:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
2024-12-08 22:48:40 +01:00
|
|
|
|
}
|