open source is social v-it.org
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(explore): stats landing page, did filter, beacon skill discovery

Default route now renders stats view instead of caps
Add explicit #caps hash route and update all href="#" → href="#caps"
Add did query parameter to /api/skills for publisher filtering
Beacon detail view fetches and displays skills from cap publishers

+24 -5
+18 -5
explore/public/index.html
··· 720 720 721 721 <main id="content"> 722 722 <nav class="sub-nav"> 723 - <a href="#">caps</a> 723 + <a href="#caps">caps</a> 724 724 <a href="#skills">skills</a> 725 725 <a href="#beacons">beacons</a> 726 726 <a href="#stats">stats</a> ··· 811 811 } 812 812 return { view: 'skills' }; 813 813 } 814 + if (hash === 'caps') return { view: 'caps' }; 814 815 if (hash === 'stats') return { view: 'stats' }; 815 - return { view: 'caps' }; 816 + return { view: 'stats' }; 816 817 } 817 818 818 819 function updateNav() { 819 820 const route = getRoute(); 820 821 document.querySelectorAll('.sub-nav a').forEach(function(a) { 821 822 const href = a.getAttribute('href'); 822 - if (route.view === 'caps' || route.view === 'cap') a.classList.toggle('active', href === '#'); 823 + if (route.view === 'caps' || route.view === 'cap') a.classList.toggle('active', href === '#caps'); 823 824 else if (route.view === 'skills' || route.view === 'skill') a.classList.toggle('active', href === '#skills'); 824 825 else if (route.view === 'beacons' || route.view === 'beacon') a.classList.toggle('active', href === '#beacons'); 825 826 else if (route.view === 'stats') a.classList.toggle('active', href === '#stats'); ··· 949 950 async function renderCapDetail(el, ref) { 950 951 var data = await api('cap?ref=' + encodeURIComponent(ref)); 951 952 if (!data.cap) { 952 - el.innerHTML = '<div class="not-found"><a href="#" class="back-link">&larr; back to caps</a><p><strong>Cap not found.</strong></p><p>No cap with ref <code>' + esc(ref) + '</code> was found.</p></div>'; 953 + el.innerHTML = '<div class="not-found"><a href="#caps" class="back-link">&larr; back to caps</a><p><strong>Cap not found.</strong></p><p>No cap with ref <code>' + esc(ref) + '</code> was found.</p></div>'; 953 954 return; 954 955 } 955 956 var cap = data.cap; ··· 973 974 var beacon = cap.beacon ? '<a href="#beacon/' + encodeURIComponent(cap.beacon) + '">' + esc(cap.beacon) + '</a>' : ''; 974 975 var metaParts = [author, beacon, time].filter(Boolean); 975 976 976 - var html = '<a href="#" class="back-link">&larr; caps</a>'; 977 + var html = '<a href="#caps" class="back-link">&larr; caps</a>'; 977 978 html += '<div class="detail-header">'; 978 979 html += '<div class="detail-title">' + title + kindBadge + '</div>'; 979 980 html += '<div class="detail-meta">' + metaParts.join(' &middot; ') + '</div>'; ··· 1145 1146 capsContainer = document.getElementById('caps-list'); 1146 1147 capsContainer.innerHTML = data.caps.map(renderCapItem).join(''); 1147 1148 appendLoadMore(el); 1149 + 1150 + // Fetch skills from this beacon's publishers 1151 + const dids = [...new Set(data.caps.map(function(c) { return c.did; }).filter(Boolean))]; 1152 + if (dids.length > 0) { 1153 + const skillsUrl = 'skills?' + dids.map(function(d) { return 'did=' + encodeURIComponent(d); }).join('&'); 1154 + const skillsData = await api(skillsUrl); 1155 + if (skillsData.skills && skillsData.skills.length > 0) { 1156 + const skillsHtml = '<hr><h3>skills from these publishers</h3>' + 1157 + '<div id="beacon-skills-list">' + skillsData.skills.map(renderSkillItem).join('') + '</div>'; 1158 + el.insertAdjacentHTML('beforeend', skillsHtml); 1159 + } 1160 + } 1148 1161 } 1149 1162 1150 1163 async function renderBeacons(el) {
+6
explore/src/api.js
··· 154 154 bindings.push(tag); 155 155 } 156 156 157 + const dids = searchParams.getAll('did'); 158 + if (dids.length > 0) { 159 + conditions.push('s.did IN (' + dids.map(function() { return '?'; }).join(', ') + ')'); 160 + bindings.push(...dids); 161 + } 162 + 157 163 if (cursor) { 158 164 conditions.push('s.id < ?'); 159 165 bindings.push(cursor);