A community-maintained directory of Bluesky Personal Data Servers (PDS).
at main 3.7 kB view raw
1// Load PDS data and populate table 2document.addEventListener('DOMContentLoaded', function() { 3 loadPDSData(); 4}); 5 6async function loadPDSData() { 7 const loading = document.getElementById('loading'); 8 const content = document.getElementById('content'); 9 const tableBody = document.getElementById('table-body'); 10 const noData = document.getElementById('no-data'); 11 const serverCount = document.getElementById('server-count'); 12 13 try { 14 const response = await fetch('./pdslist.json'); 15 const pdsData = await response.json(); 16 17 // Hide loading 18 loading.style.display = 'none'; 19 content.style.display = 'block'; 20 21 if (pdsData.length === 0) { 22 noData.style.display = 'block'; 23 return; 24 } 25 26 // Update server count 27 serverCount.textContent = pdsData.length; 28 29 // Populate table 30 pdsData.forEach(pds => { 31 const row = createTableRow(pds); 32 tableBody.appendChild(row); 33 }); 34 35 } catch (error) { 36 console.error('Error loading PDS data:', error); 37 loading.innerHTML = '<p style="color: red;">Error loading database. Please check console.</p>'; 38 } 39} 40 41function createTableRow(pds) { 42 const row = document.createElement('tr'); 43 44 // URL 45 const urlCell = document.createElement('td'); 46 const urlLink = document.createElement('a'); 47 urlLink.href = pds.url; 48 urlLink.target = '_blank'; 49 urlLink.textContent = pds.url; 50 urlCell.appendChild(urlLink); 51 row.appendChild(urlCell); 52 53 // Handles 54 const handlesCell = document.createElement('td'); 55 if (pds.supportedHandles && pds.supportedHandles.length > 0) { 56 handlesCell.textContent = pds.supportedHandles.join(', '); 57 } else { 58 handlesCell.textContent = 'N/A'; 59 } 60 row.appendChild(handlesCell); 61 62 // Maintainer 63 const maintainerCell = document.createElement('td'); 64 if (pds.maintainer) { 65 const link = document.createElement('a'); 66 link.href = `https://madebydanny.uk/followonbsky?did=${pds.maintainer}`; 67 link.target = '_blank'; 68 link.textContent = pds.maintainer; 69 maintainerCell.appendChild(link); 70 } else { 71 maintainerCell.textContent = '—'; 72 } 73 row.appendChild(maintainerCell); 74 75 // Contact Email 76 const emailCell = document.createElement('td'); 77 if (pds.contactEmail) { 78 const link = document.createElement('a'); 79 link.href = `mailto:${pds.contactEmail}`; 80 link.textContent = pds.contactEmail; 81 emailCell.appendChild(link); 82 } else { 83 emailCell.textContent = '—'; 84 } 85 row.appendChild(emailCell); 86 87 // Invite Code Required 88 const inviteCell = document.createElement('td'); 89 inviteCell.textContent = pds.inviteCodeRequired ? 'Yes' : 'No'; 90 row.appendChild(inviteCell); 91 92 // Terms of Service 93 const tosCell = document.createElement('td'); 94 if (pds.tosUrl) { 95 const link = document.createElement('a'); 96 link.href = pds.tosUrl; 97 link.target = '_blank'; 98 link.rel = 'noopener noreferrer'; 99 link.textContent = 'Link'; 100 tosCell.appendChild(link); 101 } else { 102 tosCell.textContent = '—'; 103 } 104 row.appendChild(tosCell); 105 106 // Privacy Policy 107 const privacyCell = document.createElement('td'); 108 if (pds.privacyUrl) { 109 const link = document.createElement('a'); 110 link.href = pds.privacyUrl; 111 link.target = '_blank'; 112 link.rel = 'noopener noreferrer'; 113 link.textContent = 'Link'; 114 privacyCell.appendChild(link); 115 } else { 116 privacyCell.textContent = '—'; 117 } 118 row.appendChild(privacyCell); 119 120 return row; 121}