kirche-im-netz.Startodon-Hub/code.js
Alexander Müller 66036d92c9 code optimiert
2024-12-09 23:06:48 +01:00

282 lines
9.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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';
fetchProfile(kit.author, { updateElement: 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;
}
/**
* 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 => {
fetchProfile(accountUrl, { createCard: true })
.then(card => body.appendChild(card))
.catch(error => console.error(`Fehler beim Laden des Accounts: ${accountUrl}`, error));
});
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 aktualisiert ein DOM-Element oder erstellt eine Profil-Kachel.
*/
function fetchProfile(profileUrl, options = {}) {
const { updateElement = null, createCard = false } = options;
return new Promise((resolve, reject) => {
try {
const url = new URL(profileUrl);
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 => {
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);
}
})
.catch(error => {
console.error(`Fehler beim Abrufen des Profils für ${profileUrl}:`, error);
reject(error);
});
}
} catch (error) {
console.error('Ungültige URL:', profileUrl, 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}`;
// Ergänze die Klasse basierend auf der Instanz
const serverClass = getServerClass(instance);
if (serverClass) {
serverHandleElement.classList.add(serverClass);
}
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': 'liboriSocial',
'reliverse.social': 'reliverseSocial',
'kirche.social': 'kircheSocial',
'katholisch.social': 'katholischSocial'
};
return serverClasses[instance] || null;
}
/**
* 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;
}
}