Mercurial
comparison hg-web/src/index.js @ 135:ffb764d2fcc5
[HgWeb] Updated hg web so it works
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Fri, 09 Jan 2026 11:17:20 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 133:902e29c38d66 | 135:ffb764d2fcc5 |
|---|---|
| 1 const API_BASE = '/api/repo'; | |
| 2 | |
| 3 function getCurrentPath() { | |
| 4 const params = new URLSearchParams(window.location.search); | |
| 5 return params.get('path') || ''; | |
| 6 } | |
| 7 | |
| 8 function renderBreadcrumb(path) { | |
| 9 const breadcrumb = document.getElementById('breadcrumb'); | |
| 10 if (!path) { | |
| 11 breadcrumb.innerHTML = '<a href="/">Root</a>'; | |
| 12 return; | |
| 13 } | |
| 14 | |
| 15 const parts = path.split('/').filter(p => p); | |
| 16 let currentPath = ''; | |
| 17 let html = '<a href="/">Root</a>'; | |
| 18 | |
| 19 parts.forEach((part, index) => { | |
| 20 currentPath += (currentPath ? '/' : '') + part; | |
| 21 html += ` <span>/</span> `; | |
| 22 if (index === parts.length - 1) { | |
| 23 html += `<span>${part}</span>`; | |
| 24 } else { | |
| 25 html += `<a href="?path=${encodeURIComponent(currentPath)}">${part}</a>`; | |
| 26 } | |
| 27 }); | |
| 28 | |
| 29 breadcrumb.innerHTML = html; | |
| 30 } | |
| 31 | |
| 32 function renderFiles(files, directories) { | |
| 33 if (!files || files.length === 0) { | |
| 34 fileList.style.display = 'none'; | |
| 35 emptyState.style.display = 'block'; | |
| 36 return; | |
| 37 } | |
| 38 | |
| 39 emptyState.style.display = 'none'; | |
| 40 fileList.style.display = 'block'; | |
| 41 | |
| 42 let html = ''; | |
| 43 directories.forEach(file => { | |
| 44 const icon = '📁'; | |
| 45 const className = file.type; | |
| 46 const href = `?path=${encodeURIComponent(file.abspath)}`; | |
| 47 const target = ''; | |
| 48 | |
| 49 html += ` | |
| 50 <div class="file-item ${className}"> | |
| 51 <span class="icon">${icon}</span> | |
| 52 <span class="name"> | |
| 53 <a href="${href}" ${target}>${file.basename}</a> | |
| 54 </span> | |
| 55 </div> | |
| 56 `; | |
| 57 }); | |
| 58 files.forEach(file => { | |
| 59 const icon = '📄'; | |
| 60 const className = file.type; | |
| 61 const href = `/api/repo/file?path=${encodeURIComponent(file.abspath)}`; | |
| 62 const target = 'target="_blank"'; | |
| 63 | |
| 64 html += ` | |
| 65 <div class="file-item ${className}"> | |
| 66 <span class="icon">${icon}</span> | |
| 67 <span class="name"> | |
| 68 <a href="${href}" ${target}>${file.basename}</a> | |
| 69 </span> | |
| 70 </div> | |
| 71 `; | |
| 72 }); | |
| 73 | |
| 74 fileList.innerHTML = html; | |
| 75 } | |
| 76 | |
| 77 async function loadReadme(path) { | |
| 78 const readmeSection = document.getElementById('readmeSection'); | |
| 79 const readmeContent = document.getElementById('readmeContent'); | |
| 80 | |
| 81 try { | |
| 82 const readmePath = path ? `${path}/README.md` : 'README.md'; | |
| 83 const response = await fetch(`/api/repo/readme?path=${encodeURIComponent(readmePath)}`); | |
| 84 | |
| 85 if (response.ok) { | |
| 86 const markdown = await response.text(); | |
| 87 readmeSection.style.display = 'block'; | |
| 88 renderMarkdown(readmeContent, markdown); | |
| 89 } else { | |
| 90 readmeSection.style.display = 'none'; | |
| 91 } | |
| 92 } catch (error) { | |
| 93 readmeSection.style.display = 'none'; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 async function loadDirectory(path) { | |
| 98 try { | |
| 99 const url = path ? `${API_BASE}/list?path=${encodeURIComponent(path)}` : `${API_BASE}/list`; | |
| 100 const response = await fetch(url); | |
| 101 const data = await response.json(); | |
| 102 | |
| 103 if (data.error) { | |
| 104 throw new Error(data.error); | |
| 105 } | |
| 106 | |
| 107 const { files, directories } = data; | |
| 108 | |
| 109 renderBreadcrumb(path); | |
| 110 renderFiles(files, directories); | |
| 111 loadReadme(path); | |
| 112 } catch (error) { | |
| 113 console.error('Error loading directory:', error); | |
| 114 document.getElementById('fileList').innerHTML = ` | |
| 115 <div class="error-message">Error loading directory: ${error.message}</div> | |
| 116 `; | |
| 117 } | |
| 118 } | |
| 119 | |
| 120 window.addEventListener('popstate', (event) => { | |
| 121 const path = event.state?.path || ''; | |
| 122 loadDirectory(path); | |
| 123 }); | |
| 124 | |
| 125 const currentPath = getCurrentPath(); | |
| 126 loadDirectory(currentPath); |