kirche-im-netz.Startodon-Hub/code.js
2024-12-08 22:48:40 +01:00

253 lines
9.4 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 shuffleContainers = document.querySelectorAll('.shuffle-container');
const seed = Date.now();
shuffleContainers.forEach(container => {
seededShuffleChildren(container, seed);
});
const starterkits = document.querySelectorAll('.starterkit');
starterkits.forEach(kit => {
const authorAccount = kit.querySelector('.autor .account');
if (authorAccount) {
try {
const url = new URL(authorAccount.getAttribute('href'));
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://${config.homeInstance}/api/v1/accounts/lookup?acct=${handle}@${instance}`;
fetch(lookupUrl)
.then(response => response.json())
.then(data => {
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 || '';
authorAccount.prepend(avatarImage);
// Ergänze die Klasse basierend auf der Instanz
const serverClass = getServerClass(instance);
if (serverClass) {
authorAccount.classList.add(serverClass);
}
})
.catch(error => {
console.error('Fehler beim Abrufen des Autoren-Profils:', error);
});
} else {
console.error('Ungültiger Benutzer-Handle in URL:', url.href);
}
} catch (error) {
console.error('Fehler bei der Verarbeitung der URL:', error);
}
}
const accounts = kit.querySelectorAll('.account');
accounts.forEach(account => {
const parent = account.closest('.autor');
if (!parent) {
account.style.display = 'none';
}
});
// Zeige die Anzahl der Accounts auf der StarterKit-Kachel
const accountCount = kit.querySelectorAll('.account:not(.autor .account)').length;
const accountCountElement = document.createElement('div');
accountCountElement.classList.add('account-count');
accountCountElement.textContent = `${accountCount} Profile`;
kit.appendChild(accountCountElement);
// Füge Event-Listener für StarterKit-Kacheln hinzu
kit.addEventListener('click', function() {
const title = kit.querySelector('h3').textContent;
const accountsForPopup = Array.from(kit.querySelectorAll('.account')).filter(account => !account.closest('.autor'));
const popup = createRecommendationPopup(accountsForPopup, title);
document.body.appendChild(popup);
});
});
});
/**
* Funktion zum Erstellen eines Pop-ups.
* @param {NodeList} accounts - Die Liste der Accounts für das Pop-up.
* @param {string} title - Der Titel des StarterKits.
* @returns {HTMLElement} - Das erzeugte Pop-up-Element.
*/
function createRecommendationPopup(accounts, title) {
// Overlay erstellen
const overlay = document.createElement('div');
overlay.classList.add('recommendation-popup');
// Pop-up-Inhalt
const content = document.createElement('div');
content.classList.add('recommendation-popup-content');
// Header des Pop-ups
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()); // Schließen-Funktion
header.appendChild(titleElement);
header.appendChild(closeButton);
// Body des Pop-ups
const body = document.createElement('div');
body.classList.add('recommendation-popup-body');
accounts.forEach(account => {
try {
const url = new URL(account.getAttribute('href'));
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://${config.homeInstance}/api/v1/accounts/lookup?acct=${handle}@${instance}`;
fetch(lookupUrl)
.then(response => response.json())
.then(data => {
const card = createAccountCard(data, account.href, instance);
body.appendChild(card);
})
.catch(error => {
console.error('Fehler beim Abrufen des Profils:', error);
});
} else {
console.error('Ungültiger Benutzer-Handle in URL:', url.href);
}
} catch (error) {
console.error('Fehler bei der Verarbeitung der URL:', error);
}
});
// Pop-up zusammenfügen
content.appendChild(header);
content.appendChild(body);
overlay.appendChild(content);
// Event-Listener für Overlay (schließt Pop-up bei Klick auf Hintergrund)
overlay.addEventListener('click', function(event) {
if (event.target === overlay) {
overlay.remove();
}
});
return overlay;
}
/**
* Funktion zum Erstellen einer Account-Kachel.
* @param {Object} data - Die Account-Daten von der API.
* @param {string} href - Die URL des Accounts.
* @param {string} instance - Der Instanz-Name.
* @returns {HTMLElement} - Die erzeugte 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;
}
/**
* Funktion, um die Kinder eines Containers deterministisch neu anzuordnen.
* @param {HTMLElement} container - Der Container, dessen Kinder durchmischt werden sollen.
* @param {number} seed - Der Seed für das deterministische Shuffle.
*/
function seededShuffleChildren(container, seed) {
const children = Array.from(container.children);
const shuffled = seededShuffle(children, seed);
shuffled.forEach(child => container.appendChild(child));
}
/**
* Funktion für einen deterministischen Shuffle-Algorithmus.
* @param {Array} array - Das Array, das gemischt werden soll.
* @param {number} seed - Der Seed für das deterministische Shuffle.
* @returns {Array} - Das gemischte Array.
*/
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;
}
/**
* Funktion für einen deterministischen Zufallswert.
* @param {number} seed - Der Seed für den Zufallswert.
* @returns {number} - Der generierte Zufallswert.
*/
function seededRandom(seed) {
const x = Math.sin(seed++) * 10000;
return x - Math.floor(x);
}
/**
* Funktion zur Zuordnung von Instanzen zu CSS-Klassen.
* @param {string} instance - Der Name der Instanz.
* @returns {string|null} - Die zugehörige CSS-Klasse oder null, wenn keine Übereinstimmung vorliegt.
*/
function getServerClass(instance) {
const serverClasses = {
'libori.social': 'liboriSocial',
'reliverse.social': 'reliverseSocial',
'kirche.social': 'kircheSocial',
'katholisch.social': 'katholischSocial'
};
return serverClasses[instance] || null;
}