tangled vouch map with historical data
7
fork

Configure Feed

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

feat: fix sidebar

+66 -13
+4 -2
web/index.html
··· 24 24 </nav> 25 25 </header> 26 26 27 - <div id="graph-container"></div> 27 + <div id="main-area"> 28 + <div id="graph-container"></div> 29 + <div id="sidebar"></div> 30 + </div> 28 31 <div id="loading">Loading graph data...</div> 29 32 <div id="tooltip"></div> 30 - <div id="sidebar"></div> 31 33 32 34 <div id="controls"> 33 35 <div id="controls-row">
+51
web/main.js
··· 297 297 } 298 298 } 299 299 300 + function resizeCosmos() { 301 + if (!cosmograph) return; 302 + const internal = getInternalApi(cosmograph); 303 + const cosmos = internal?.cosmos; 304 + if (cosmos) cosmos.resizeCanvas(); 305 + } 306 + 300 307 function selectNode(did) { 301 308 selectedDID = did; 302 309 highlightState = computeHighlight(did); 303 310 renderSidebar(did); 304 311 sidebar.classList.add('open'); 305 312 requestAnimationFrame(() => applyHighlight()); 313 + sidebar.addEventListener('transitionend', function handler() { 314 + resizeCosmos(); 315 + sidebar.removeEventListener('transitionend', handler); 316 + }); 306 317 } 307 318 308 319 function deselectNode() { ··· 310 321 highlightState = null; 311 322 sidebar.classList.remove('open'); 312 323 applyHighlight(); 324 + sidebar.addEventListener('transitionend', function handler() { 325 + resizeCosmos(); 326 + sidebar.removeEventListener('transitionend', handler); 327 + }); 313 328 } 314 329 315 330 // --- Sidebar --- ··· 473 488 const connDid = el.dataset.did; 474 489 if (connDid) selectNode(connDid); 475 490 }); 491 + }); 492 + } 493 + 494 + function showOffGraphUser(did) { 495 + const p = profileMap[did] || {}; 496 + const handle = p.handle || ''; 497 + const avatar = p.avatar || ''; 498 + const name = handle || shortenDID(did); 499 + 500 + const profileLink = handle && handle !== '!' 501 + ? `<a class="sidebar-link" href="https://tangled.org/@${handle}" target="_blank" rel="noopener">${handle} ↗</a>` 502 + : ''; 503 + 504 + sidebar.innerHTML = ` 505 + <div class="sidebar-header"> 506 + <div class="sidebar-profile"> 507 + ${avatarHtml(avatar, name)} 508 + <div> 509 + <div class="sidebar-name">${name}</div> 510 + ${profileLink} 511 + ${handle ? `<div class="sidebar-did">${shortenDID(did)}</div>` : ''} 512 + </div> 513 + </div> 514 + <div class="sidebar-stat" style="color:var(--text-muted)">Not in current graph</div> 515 + <button class="sidebar-close" id="sidebar-close">✕</button> 516 + </div> 517 + `; 518 + 519 + sidebar.classList.add('open'); 520 + document.getElementById('sidebar-close')?.addEventListener('click', deselectNode); 521 + 522 + sidebar.addEventListener('transitionend', function handler() { 523 + resizeCosmos(); 524 + sidebar.removeEventListener('transitionend', handler); 476 525 }); 477 526 } 478 527 ··· 796 845 if (idx !== undefined) { 797 846 selectNode(did); 798 847 cosmograph.zoomToPoint(idx, 800, 6); 848 + } else { 849 + showOffGraphUser(did); 799 850 } 800 851 } 801 852 });
+11 -11
web/style.css
··· 55 55 display: flex; 56 56 justify-content: space-between; 57 57 align-items: center; 58 - z-index: 20; 58 + z-index: 30; 59 59 } 60 60 61 61 .logo { ··· 114 114 border: 1px solid var(--border-default); 115 115 border-radius: 0.25rem; 116 116 box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); 117 - z-index: 30; 117 + z-index: 35; 118 118 display: none; 119 119 min-width: 240px; 120 120 max-height: 260px; ··· 148 148 } 149 149 .search-item .search-info { overflow: hidden; } 150 150 151 - #graph-container { flex: 1; min-height: 0; overflow: hidden; } 151 + #main-area { flex: 1; min-height: 0; display: flex; } 152 + 153 + #graph-container { flex: 1; min-width: 0; overflow: hidden; } 152 154 153 155 #controls { 154 156 flex-shrink: 0; ··· 284 286 } 285 287 286 288 #sidebar { 287 - position: fixed; 288 - top: 0; 289 - right: 0; 290 - width: 320px; 291 - height: 100%; 289 + width: 0; 290 + overflow: hidden; 292 291 background: var(--bg-card); 293 292 border-left: 1px solid var(--border-default); 294 293 z-index: 25; 295 294 overflow-y: auto; 296 - transform: translateX(100%); 297 - transition: transform 0.2s ease; 295 + transition: width 0.2s ease; 298 296 display: flex; 299 297 flex-direction: column; 298 + flex-shrink: 0; 300 299 } 301 300 #sidebar.open { 302 - transform: translateX(0); 301 + width: 320px; 302 + overflow-y: auto; 303 303 } 304 304 305 305 .sidebar-header {