152 lines
6.9 KiB
JavaScript
152 lines
6.9 KiB
JavaScript
// Function to copy text to clipboard and trigger animation
|
|
function copyToClipboard(text, button) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
button.classList.add('copied');
|
|
setTimeout(() => {
|
|
button.classList.remove('copied');
|
|
}, 2000);
|
|
}).catch(err => {
|
|
console.error('Failed to copy:', err);
|
|
});
|
|
}
|
|
|
|
// Function to create a server card
|
|
function createServerCard(server, isNew = false) {
|
|
const ownerName = server.ops && server.ops.length > 0 ? server.ops[0].name : 'Unknown';
|
|
// Prefer connect2 if it's a my-mc.link subdomain, otherwise use connect
|
|
const displayConnect = server.connect2 && server.connect2.includes('.my-mc.link') ? server.connect2 : server.connect;
|
|
const serverCard = document.createElement('div');
|
|
serverCard.className = `feature-card tilt-card ${isNew ? 'new-server-animation' : ''}`;
|
|
serverCard.dataset.connect = server.connect; // Add identifier
|
|
serverCard.innerHTML = `
|
|
<div class="flex items-center mb-3">
|
|
<span class="inline-block w-3 h-3 rounded-full mr-2 ${server.online ? 'bg-green-500' : 'bg-red-500'}"></span>
|
|
<h3 class="text-xl minecraft-font text-teal-400">${ownerName}'s Server</h3>
|
|
</div>
|
|
<p class="text-sm opacity-90 leading-relaxed mb-2"><strong>MOTD:</strong> ${server.motd}</p>
|
|
<p class="text-sm opacity-90 leading-relaxed mb-2"><strong>Version:</strong> ${server.gameVersion}</p>
|
|
<p class="text-sm opacity-90 leading-relaxed mb-2"><strong>Gamemode:</strong> ${server.gamemode}</p>
|
|
<p class="text-sm opacity-90 leading-relaxed mb-2"><strong>Hardcore:</strong> ${server.hardcore ? 'Yes' : 'No'}</p>
|
|
<p class="text-sm opacity-90 leading-relaxed"><strong>Status:</strong> ${server.online ? 'Online' : 'Offline'}</p>
|
|
<div class="flex items-center text-sm opacity-90 leading-relaxed mb-2">
|
|
<strong>Connect:</strong>
|
|
<span class="ml-2">${displayConnect}</span>
|
|
<button class="copy-btn ml-4" onclick="copyToClipboard('${displayConnect}', this)" style="color: #2DD4BF;">
|
|
<svg class="clipboard" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V7a2 2 0 00-2-2h-2m-2-2h-4a2 2 0 00-2 2h8a2 2 0 01-2 2h-4a2 2 0 01-2-2z"></path>
|
|
</svg>
|
|
<svg class="checkmark" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
`;
|
|
return serverCard;
|
|
}
|
|
|
|
// Function to update server list dynamically
|
|
function updateServerList(newServers) {
|
|
const serverList = document.getElementById('server-list');
|
|
const currentCards = Array.from(serverList.children);
|
|
const currentConnects = currentCards.map(card => card.dataset.connect);
|
|
const newConnects = newServers.map(server => server.connect);
|
|
|
|
// Find new servers
|
|
const serversToAdd = newServers.filter(server => !currentConnects.includes(server.connect));
|
|
const serversToRemove = currentCards.filter(card => !newConnects.includes(card.dataset.connect));
|
|
|
|
// Remove old servers
|
|
serversToRemove.forEach(card => {
|
|
card.style.opacity = '0';
|
|
card.style.transform = 'translateY(20px)';
|
|
setTimeout(() => card.remove(), 300);
|
|
});
|
|
|
|
// Add new servers with animation
|
|
serversToAdd.forEach(server => {
|
|
const newCard = createServerCard(server, true);
|
|
serverList.insertBefore(newCard, serverList.firstChild);
|
|
});
|
|
|
|
// Update existing servers
|
|
newServers.forEach(server => {
|
|
const existingCard = currentCards.find(card => card.dataset.connect === server.connect);
|
|
if (existingCard) {
|
|
const ownerName = server.ops && server.ops.length > 0 ? server.ops[0].name : 'Unknown';
|
|
const updatedCard = createServerCard(server);
|
|
existingCard.innerHTML = updatedCard.innerHTML;
|
|
existingCard.className = updatedCard.className;
|
|
}
|
|
});
|
|
|
|
console.log('Server list updated:', {
|
|
added: serversToAdd.length,
|
|
removed: serversToRemove.length,
|
|
total: newServers.length
|
|
});
|
|
}
|
|
|
|
// Function to fetch and display servers
|
|
async function fetchServers() {
|
|
const serverList = document.getElementById('server-list');
|
|
const loadingMessage = document.getElementById('loading-message');
|
|
const errorMessage = document.getElementById('error-message');
|
|
const searchInput = document.getElementById('search-input');
|
|
|
|
try {
|
|
const response = await fetch('https://api.my-mc.link/list_all_servers_public');
|
|
const data = await response.json();
|
|
|
|
if (data.success && data.servers) {
|
|
loadingMessage.classList.add('hidden');
|
|
errorMessage.classList.add('hidden');
|
|
|
|
// Store servers globally for search filtering
|
|
window.serverData = data.servers;
|
|
|
|
// Initial render or update
|
|
if (serverList.children.length === 0) {
|
|
window.serverData.forEach(server => {
|
|
serverList.appendChild(createServerCard(server));
|
|
});
|
|
} else {
|
|
updateServerList(window.serverData);
|
|
}
|
|
|
|
// Add search event listener (only once)
|
|
if (!searchInput.dataset.listener) {
|
|
searchInput.dataset.listener = 'true';
|
|
searchInput.addEventListener('input', () => {
|
|
const searchTerm = searchInput.value.trim().toLowerCase();
|
|
const filteredServers = window.serverData.filter(server => {
|
|
const ownerName = server.ops && server.ops.length > 0 ? server.ops[0].name.toLowerCase() : 'unknown';
|
|
const motd = server.motd.toLowerCase();
|
|
const version = server.gameVersion.toLowerCase();
|
|
const status = server.online ? 'online' : 'offline';
|
|
|
|
return (
|
|
ownerName.includes(searchTerm) ||
|
|
motd.includes(searchTerm) ||
|
|
version.includes(searchTerm) ||
|
|
status.includes(searchTerm)
|
|
);
|
|
});
|
|
|
|
updateServerList(filteredServers);
|
|
});
|
|
}
|
|
} else {
|
|
throw new Error('No servers found');
|
|
}
|
|
} catch (error) {
|
|
loadingMessage.classList.add('hidden');
|
|
errorMessage.classList.remove('hidden');
|
|
console.error('Error fetching servers:', error);
|
|
}
|
|
}
|
|
|
|
// Initial fetch
|
|
fetchServers();
|
|
|
|
// Fetch servers every 60 seconds
|
|
setInterval(fetchServers, 60000); |