|
885 | 885 | // ============================================================================ |
886 | 886 | // VIRTUAL RENDERING - Only render visible items |
887 | 887 | // ============================================================================ |
888 | | - const render = (nodes, lv = 0, acc = []) => { |
889 | | - if (acc.length > MAX_RENDER) return acc; // Stop if too many |
890 | | - nodes.forEach(nd => { |
| 888 | + // Helper to build tree lines array for each node |
| 889 | + function getTreeLines(parents, isLast) { |
| 890 | + let lines = ''; |
| 891 | + for (let i = 0; i < parents.length; ++i) { |
| 892 | + lines += `<span class="tree-vline" style="visibility:${parents[i] ? 'visible' : 'hidden'}"></span>`; |
| 893 | + } |
| 894 | + // For the current node, add a connector (├ or └) |
| 895 | + if (parents.length > 0) { |
| 896 | + lines += `<span class="tree-vline tree-branch" style="height:22px;${isLast ? 'border-left:2px solid transparent;' : ''}"></span>`; |
| 897 | + } |
| 898 | + return lines; |
| 899 | + } |
| 900 | + |
| 901 | + const render = (nodes, lv = 0, acc = [], parents = []) => { |
| 902 | + if (acc.length > MAX_RENDER) return acc; |
| 903 | + nodes.forEach((nd, idx) => { |
891 | 904 | const ic = ico(nd.n, nd.t === 'd'); |
892 | 905 | const has = nd.t === 'd' && nd.kids.size > 0; |
893 | 906 | const sz = nd.f ? bytes(nd.f.size) : ''; |
| 907 | + const isLast = idx === nodes.length - 1; |
| 908 | + // Tree lines |
| 909 | + const lines = getTreeLines(parents, isLast); |
| 910 | + // Arrow SVGs |
| 911 | + let arrow = ''; |
| 912 | + if (has) { |
| 913 | + arrow = `<img class="tree-arrow" src="public/arrowRight.svg" data-arrow="right" style="display:inline;" />`; |
| 914 | + } else { |
| 915 | + arrow = `<span class="tree-arrow-placeholder"></span>`; |
| 916 | + } |
894 | 917 | acc.push({ |
895 | | - html: `<div class="tree-item ${nd.ig ? 'ignored' : ''}" data-path="${nd.full}"> |
| 918 | + html: `<div class="tree-item${nd.ig ? ' ignored' : ''}${has ? ' folder' : ''}" data-path="${nd.full}"> |
896 | 919 | <div class="tree-item-content" data-level="${lv}"> |
| 920 | + <span class="tree-lines">${lines}</span> |
897 | 921 | <button class="expand-btn" style="visibility:${has ? 'visible' : 'hidden'}"> |
898 | | - <span class="material-symbols-outlined">chevron_right</span> |
| 922 | + ${arrow} |
899 | 923 | </button> |
900 | 924 | <div class="file-icon ${ic.cls}"> |
901 | 925 | <img src="${ic.url}" alt="${nd.n}" class="vscode-icon" onerror="this.style.display='none'" /> |
|
906 | 930 | </label> |
907 | 931 | ${sz ? `<span class="file-size">${sz}</span>` : ''} |
908 | 932 | </div> |
909 | | - ${has ? `<div class="tree-children">${renderSub(Array.from(nd.kids.values()), lv + 1)}</div>` : ''} |
| 933 | + ${has ? `<div class="tree-children">${renderSub(Array.from(nd.kids.values()), lv + 1, parents.concat(!isLast))}</div>` : ''} |
910 | 934 | </div>` |
911 | 935 | }); |
912 | 936 | }); |
913 | 937 | return acc; |
914 | 938 | }; |
915 | | - const renderSub = (nodes, lv) => render(nodes, lv, []).map(x => x.html).join(''); |
| 939 | + // Pass parents array for lines |
| 940 | + const renderSub = (nodes, lv, parents) => render(nodes, lv, [], parents).map(x => x.html).join(''); |
916 | 941 | // ============================================================================ |
917 | 942 | // FILE LOADING - ASYNC CHUNKS (ENHANCED FILTERING & UI UPDATE) |
918 | 943 | // ============================================================================ |
|
1380 | 1405 | if (btn) { |
1381 | 1406 | const item = btn.closest('.tree-item'); |
1382 | 1407 | const kids = item.querySelector('.tree-children'); |
| 1408 | + const arrowImg = btn.querySelector('.tree-arrow'); |
1383 | 1409 | if (kids) { |
1384 | 1410 | const open = kids.classList.toggle('open'); |
1385 | 1411 | btn.classList.toggle('expanded', open); |
1386 | | - btn.querySelector('.material-symbols-outlined').textContent = open ? 'expand_more' : 'chevron_right'; |
| 1412 | + if (arrowImg) { |
| 1413 | + arrowImg.src = open ? 'public/arrowDown.svg' : 'public/arrowRight.svg'; |
| 1414 | + arrowImg.setAttribute('data-arrow', open ? 'down' : 'right'); |
| 1415 | + } |
1387 | 1416 | } |
1388 | 1417 | return; |
1389 | 1418 | } |
|
0 commit comments