this repo has no description
at main 81 lines 2.8 kB view raw
1--- 2import { DID } from '../../lib/atproto'; 3--- 4 5<div id="notesPanel" class="tab-panel"> 6 <div class="loading"> 7 <span class="loading-dot"></span> 8 <span class="loading-dot"></span> 9 <span class="loading-dot"></span> 10 </div> 11</div> 12 13<script is:inline define:vars={{ DID }}> 14(function() { 15 var panel = document.getElementById('notesPanel'); 16 17 function esc(s) { return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); } 18 19 function formatDate(d) { 20 return new Date(d).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); 21 } 22 23 async function resolvePDS() { 24 var res = await fetch('https://plc.directory/' + DID); 25 var doc = await res.json(); 26 var svc = doc.service.find(function(s) { return s.type === 'AtprotoPersonalDataServer'; }); 27 return svc.serviceEndpoint; 28 } 29 30 async function listAllRecords(pds, collection) { 31 var records = [], cursor = null; 32 do { 33 var url = new URL(pds + '/xrpc/com.atproto.repo.listRecords'); 34 url.searchParams.set('repo', DID); 35 url.searchParams.set('collection', collection); 36 url.searchParams.set('limit', '100'); 37 if (cursor) url.searchParams.set('cursor', cursor); 38 var res = await fetch(url); 39 if (!res.ok) throw new Error('PDS error ' + res.status); 40 var data = await res.json(); 41 records = records.concat(data.records); 42 cursor = data.cursor || null; 43 } while (cursor); 44 return records; 45 } 46 47 async function load() { 48 try { 49 var pds = await resolvePDS(); 50 var records = await listAllRecords(pds, 'computer.aetheros.textpad.text'); 51 var notes = records.map(function(r) { return r.value; }); 52 notes.sort(function(a, b) { return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(); }); 53 54 if (!notes.length) { panel.innerHTML = '<div class="empty-state">No notes yet</div>'; return; } 55 56 panel.innerHTML = ''; 57 notes.forEach(function(note) { 58 var el = document.createElement('div'); 59 el.className = 'card note-card'; 60 el.innerHTML = '<div class="card-title">' + esc(note.title) + '</div>' 61 + '<div class="card-meta">' + formatDate(note.updatedAt) + '</div>' 62 + (note.body ? '<div class="card-desc note-body">' + esc(note.body) + '</div>' : ''); 63 panel.appendChild(el); 64 }); 65 } catch(e) { 66 panel.innerHTML = '<div class="error-state">Could not load notes</div>'; 67 } 68 } 69 70 window.addEventListener('tab-switch', function(e) { 71 if (e.detail === 'notes' && !panel.dataset.loaded) { 72 panel.dataset.loaded = '1'; 73 load(); 74 } 75 }); 76})(); 77</script> 78 79<style is:global> 80 .note-body { font-size: 0.88rem; white-space: pre-wrap; } 81</style>