mirror of
https://codeberg.org/kirche-im-netz/Startodon-Hub.git
synced 2025-06-21 00:26:08 +02:00
193 lines
8.8 KiB
JavaScript
193 lines
8.8 KiB
JavaScript
|
const instanceColor = getComputedStyle(document.documentElement).getPropertyValue('--instance-color').trim() || '#ff6347';
|
||
|
const backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color').trim() || '#ff6347';
|
||
|
|
||
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
const accountsContainer = document.querySelector('#account-list');
|
||
|
let accounts = Array.from(document.querySelectorAll('.account'));
|
||
|
|
||
|
// Separate Favoriten und gemischte Accounts
|
||
|
const favoriteAccounts = accounts.filter(account => account.dataset.favorite === "true");
|
||
|
const otherAccounts = accounts.filter(account => !account.dataset.favorite);
|
||
|
|
||
|
// Mische übrige Accounts
|
||
|
const seed = Date.now();
|
||
|
const shuffledOtherAccounts = seededShuffle(otherAccounts, seed);
|
||
|
|
||
|
const sortedAccounts = [...favoriteAccounts, ...shuffledOtherAccounts];
|
||
|
|
||
|
accountsContainer.innerHTML = '';
|
||
|
sortedAccounts.forEach(account => accountsContainer.appendChild(account));
|
||
|
|
||
|
sortedAccounts.forEach(function(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 link = document.createElement('a');
|
||
|
link.classList.add('account-card-link');
|
||
|
link.href = account.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 || handle;
|
||
|
|
||
|
const handleElement = document.createElement('p');
|
||
|
handleElement.classList.add('handle');
|
||
|
|
||
|
const serverHandleElement = document.createElement('span');
|
||
|
serverHandleElement.classList.add('server-handle');
|
||
|
serverHandleElement.textContent = `@${instance}`;
|
||
|
|
||
|
if (instance === config.homeInstance) {
|
||
|
serverHandleElement.style.backgroundColor = instanceColor;
|
||
|
}
|
||
|
|
||
|
handleElement.innerHTML = `@${data.username}`;
|
||
|
handleElement.appendChild(serverHandleElement);
|
||
|
|
||
|
// QR-Code Button
|
||
|
const qrButton = document.createElement('button');
|
||
|
qrButton.classList.add('qr-code-button');
|
||
|
qrButton.innerHTML = `
|
||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="${backgroundColor}">
|
||
|
<path d="M0 80C0 53.5 21.5 32 48 32l96 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-96 0c-26.5 0-48-21.5-48-48L0 80zM64 96l0 64 64 0 0-64L64 96zM0 336c0-26.5 21.5-48 48-48l96 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-96 0c-26.5 0-48-21.5-48-48l0-96zm64 16l0 64 64 0 0-64-64 0zM304 32l96 0c26.5 0 48 21.5 48 48l0 96c0 26.5-21.5 48-48 48l-96 0c-26.5 0-48-21.5-48-48l0-96c0-26.5 21.5-48 48-48zm80 64l-64 0 0 64 64 0 0-64zM256 304c0-8.8 7.2-16 16-16l64 0c8.8 0 16 7.2 16 16s7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s7.2-16 16-16s16 7.2 16 16l0 96c0 8.8-7.2 16-16 16l-64 0c-8.8 0-16-7.2-16-16s-7.2-16-16-16s-16 7.2-16 16l0 64c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-160zM368 480a16 16 0 1 1 0-32 16 16 0 1 1 0 32zm64 0a16 16 0 1 1 0-32 16 16 0 1 1 0 32z"/>
|
||
|
</svg>
|
||
|
`;
|
||
|
qrButton.addEventListener('click', function(event) {
|
||
|
event.preventDefault();
|
||
|
showQrPopup(link.href);
|
||
|
});
|
||
|
|
||
|
infoContainer.appendChild(displayNameElement);
|
||
|
infoContainer.appendChild(handleElement);
|
||
|
card.appendChild(avatarImage);
|
||
|
card.appendChild(infoContainer);
|
||
|
card.appendChild(qrButton);
|
||
|
link.appendChild(card);
|
||
|
|
||
|
account.replaceWith(link);
|
||
|
})
|
||
|
.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);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// QR-Code anzeigen
|
||
|
function showQrPopup(profileUrl) {
|
||
|
// QR-Overlay für Abdunkelung
|
||
|
const overlay = document.createElement('div');
|
||
|
overlay.classList.add('qr-overlay');
|
||
|
|
||
|
// Popup-Container
|
||
|
const popup = document.createElement('div');
|
||
|
popup.classList.add('qr-popup');
|
||
|
|
||
|
// Schließen-Button
|
||
|
const closeButton = document.createElement('button');
|
||
|
closeButton.classList.add('close-popup');
|
||
|
closeButton.textContent = 'x';
|
||
|
closeButton.innerHTML = `
|
||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="13" height="13" fill="${backgroundColor}"><!--!Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M376.6 84.5c11.3-13.6 9.5-33.8-4.1-45.1s-33.8-9.5-45.1 4.1L192 206 56.6 43.5C45.3 29.9 25.1 28.1 11.5 39.4S-3.9 70.9 7.4 84.5L150.3 256 7.4 427.5c-11.3 13.6-9.5 33.8 4.1 45.1s33.8 9.5 45.1-4.1L192 306 327.4 468.5c11.3 13.6 31.5 15.4 45.1 4.1s15.4-31.5 4.1-45.1L233.7 256 376.6 84.5z"/></svg>
|
||
|
`;
|
||
|
closeButton.addEventListener('click', function () {
|
||
|
overlay.remove();
|
||
|
});
|
||
|
|
||
|
// Event-Listener für das Overlay (schließt Popup bei Klick auf Hintergrund)
|
||
|
overlay.addEventListener('click', function (event) {
|
||
|
if (event.target === overlay) { // Nur schließen, wenn außerhalb des Popups geklickt wurde
|
||
|
overlay.remove();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// QR-Code-Container
|
||
|
const qrContainer = document.createElement('div');
|
||
|
qrContainer.classList.add('qr-code-container');
|
||
|
|
||
|
// QR-Code mit kjua generieren
|
||
|
const qrCode = kjua({
|
||
|
render: 'canvas',
|
||
|
text: profileUrl,
|
||
|
size: 200,
|
||
|
quiet: 2,
|
||
|
ecLevel: 'H',
|
||
|
});
|
||
|
|
||
|
qrContainer.appendChild(qrCode);
|
||
|
|
||
|
// Extrahiere User-Handle und Server-Handle
|
||
|
const url = new URL(profileUrl);
|
||
|
const pathParts = url.pathname.split('/');
|
||
|
const userHandle = pathParts[1] || '@unbekannt';
|
||
|
const serverHandle = url.hostname || 'unbekannt';
|
||
|
|
||
|
// Handle unter dem QR-Code
|
||
|
const handleContainer = document.createElement('p');
|
||
|
handleContainer.classList.add('qr-handle');
|
||
|
|
||
|
const userHandleText = document.createTextNode(userHandle);
|
||
|
|
||
|
const serverHandleSpan = document.createElement('span');
|
||
|
serverHandleSpan.classList.add('qr-server-handle');
|
||
|
serverHandleSpan.textContent = `@${serverHandle}`;
|
||
|
|
||
|
// Dynamisch die Hintergrundfarbe für Variable "config.homeInstance" setzen
|
||
|
if (serverHandle === config.homeInstance) {
|
||
|
serverHandleSpan.style.backgroundColor = instanceColor;
|
||
|
qrCode.style.borderColor = instanceColor;
|
||
|
}
|
||
|
|
||
|
handleContainer.appendChild(userHandleText);
|
||
|
handleContainer.appendChild(serverHandleSpan);
|
||
|
|
||
|
// Popup zusammenfügen
|
||
|
popup.appendChild(closeButton);
|
||
|
popup.appendChild(qrContainer);
|
||
|
popup.appendChild(handleContainer);
|
||
|
|
||
|
// Overlay zusammenfügen
|
||
|
overlay.appendChild(popup);
|
||
|
document.body.appendChild(overlay);
|
||
|
}
|
||
|
|
||
|
function seededRandom(seed) {
|
||
|
let x = Math.sin(seed++) * 10000;
|
||
|
return x - Math.floor(x);
|
||
|
}
|
||
|
|
||
|
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]];
|
||
|
seed++;
|
||
|
}
|
||
|
return array;
|
||
|
}
|