@@ -41,9 +41,12 @@ function parseRepoUrl(rawUrl) {
4141 let owner = u . hostname ;
4242 let repo = parts [ parts . length - 1 ] || u . hostname ;
4343
44+ // If path has /git/, take owner = first segment (the user/pod owner),
45+ // repo = segment after /git/. Handles both /<user>/git/<repo> and
46+ // /<user>/.../git/<repo> patterns.
4447 const gitIndex = parts . indexOf ( 'git' ) ;
45- if ( gitIndex >= 0 && parts [ gitIndex - 1 ] && parts [ gitIndex + 1 ] ) {
46- owner = parts [ gitIndex - 1 ] ;
48+ if ( gitIndex >= 0 && parts [ gitIndex + 1 ] ) {
49+ owner = parts [ 0 ] ;
4750 repo = parts [ gitIndex + 1 ] ;
4851 }
4952 repo = repo . replace ( / \. g i t $ / , '' ) ;
@@ -295,110 +298,97 @@ function App() {
295298 ${ error && html `< div class ="error "> ${ error } </ div > ` }
296299 ${ loading && html `< p class ="loading "> Loading…</ p > ` }
297300
298- ${ repoReady && ( ( ) => {
299- const { owner, repo } = parseRepoUrl ( url ) ;
300- return html `
301- < div class ="repo-header ">
302- < span class ="repo-breadcrumb ">
303- < span class ="owner "> ${ owner } </ span >
304- < span class ="separator "> /</ span >
305- < strong class ="repo-name "> ${ repo } </ strong >
306- </ span >
307- </ div >
308- ` ;
309- } ) ( ) }
310-
311- ${ repoReady && ! fileView && html `
312- < div class ="tabs ">
313- < a href ="# " class =${ view === 'files' ? 'tab active' : 'tab' } onClick =${ ( e ) => switchView ( e , 'files' ) } > Code</ a >
314- < a href ="# " class =${ view === 'commits' ? 'tab active' : 'tab' } onClick =${ ( e ) => switchView ( e , 'commits' ) } > Commits${ commits ? ` (${ commits . length } )` : '' } </ a >
315- </ div >
316- ` }
317-
318- ${ showFiles && latestCommit && html `
319- < div class ="latest-commit ">
320- < span class ="commit-author "> ${ latestCommit . author } </ span >
321- < span class ="commit-msg "> ${ latestCommit . message } </ span >
322- < span class ="oid "> ${ latestCommit . oid . slice ( 0 , 8 ) } </ span >
323- < span class ="meta "> ${ relativeTime ( latestCommit . timestamp ) } </ span >
301+ ${ repoReady && html `
302+ < div class ="repo-header ">
303+ < span class ="repo-breadcrumb ">
304+ < span class ="owner "> ${ parseRepoUrl ( url ) . owner } </ span >
305+ < span class ="separator "> /</ span >
306+ < strong class ="repo-name "> ${ parseRepoUrl ( url ) . repo } </ strong >
307+ </ span >
324308 </ div >
325- ` }
326-
327- ${ fileView && html `
328- < p class ="meta breadcrumb ">
329- < a href ="# " onClick =${ ( e ) => switchView ( e , 'files' ) } > ← back to files</ a >
330- < span class ="separator "> /</ span >
331- < span class ="path "> ${ fileView . path } </ span >
332- < span class ="oid "> ${ fileView . oid ?. slice ( 0 , 8 ) } </ span >
333- </ p >
334-
335- ${ fileView . kind === 'markdown' && html `
336- < div class ="readme " dangerouslySetInnerHTML =${ { __html : fileView . html } } > </ div >
337- ` }
338- ${ fileView . kind === 'text' && html `
339- < pre class ="file-content "> < code > ${ fileView . text } </ code > </ pre >
340- ` }
341- ${ fileView . kind === 'image' && html `
342- < div class ="file-content image "> < img src =${ fileView . src } alt =${ fileView . path } /> </ div >
343- ` }
344- ${ fileView . kind === 'binary' && html `
345- < p class ="meta "> Binary file (${ fileView . size } bytes) — preview not shown.</ p >
346- ` }
347- ${ fileView . kind === 'too-large' && html `
348- < p class ="meta "> File too large to display (${ fileView . size } bytes).</ p >
349- ` }
350- ` }
351309
352- ${ showFiles && tree && tree . length > 0 && html `
353- < ul class ="file-list ">
354- ${ tree . map ( ( e ) => html `
355- < li >
356- < span class ="file-icon "> ${ e . type === 'tree' ? '\u{1F4C1}' : '\u{1F4C4}' } </ span >
357- ${ e . type === 'blob'
358- ? html `< a href ="?repo=${ encodeURIComponent ( url ) } &path= ${ encodeURIComponent ( e . path ) } " onClick =${ ( ev ) => onFileClick ( ev , e . path , e . type ) } > ${ e . path } </ a > `
359- : html `< span > ${ e . path } </ span > `
360- }
361- </ li >
362- ` ) }
363- </ ul >
364- ` }
365-
366- ${ showFiles && readmeHtml && html `
367- < h2 > README</ h2 >
368- < div class ="readme " dangerouslySetInnerHTML =${ { __html : readmeHtml } } > </ div >
369- ` }
370-
371- ${ showCommits && commitsLoading && html `< p class ="loading "> Loading commits…</ p > ` }
372-
373- ${ showCommits && commits && commits . length > 0 && html `
374- < ul class ="commit-list ">
375- ${ commits . map ( ( c ) => html `
376- < li class ="commit ">
377- < div class ="commit-message "> ${ c . commit . message . split ( '\n' ) [ 0 ] } </ div >
378- < div class ="commit-meta ">
379- < span class ="commit-author "> ${ c . commit . author . name } </ span >
380- < span > committed ${ relativeTime ( c . commit . author . timestamp ) } </ span >
381- < span class ="oid "> ${ c . oid . slice ( 0 , 8 ) } </ span >
310+ < div class ="layout ">
311+ < div class ="main ">
312+ ${ ! fileView && html `
313+ < div class ="tabs ">
314+ < a href ="# " class =${ view === 'files' ? 'tab active' : 'tab' } onClick =${ ( e ) => switchView ( e , 'files' ) } > Code</ a >
315+ < a href ="# " class =${ view === 'commits' ? 'tab active' : 'tab' } onClick =${ ( e ) => switchView ( e , 'commits' ) } > Commits${ commits ? ` (${ commits . length } )` : '' } </ a >
382316 </ div >
383- </ li >
384- ` ) }
385- </ ul >
386- ` }
317+ ` }
318+
319+ ${ fileView && html `
320+ < p class ="meta breadcrumb ">
321+ < a href ="# " onClick =${ ( e ) => switchView ( e , 'files' ) } > ← back to files</ a >
322+ < span class ="separator "> /</ span >
323+ < span class ="path "> ${ fileView . path } </ span >
324+ < span class ="oid "> ${ fileView . oid ?. slice ( 0 , 8 ) } </ span >
325+ </ p >
326+
327+ ${ fileView . kind === 'markdown' && html `< div class ="readme " dangerouslySetInnerHTML =${ { __html : fileView . html } } > </ div > ` }
328+ ${ fileView . kind === 'text' && html `< pre class ="file-content "> < code > ${ fileView . text } </ code > </ pre > ` }
329+ ${ fileView . kind === 'image' && html `< div class ="file-content image "> < img src =${ fileView . src } alt =${ fileView . path } /> </ div > ` }
330+ ${ fileView . kind === 'binary' && html `< p class ="meta "> Binary file (${ fileView . size } bytes) — preview not shown.</ p > ` }
331+ ${ fileView . kind === 'too-large' && html `< p class ="meta "> File too large to display (${ fileView . size } bytes).</ p > ` }
332+ ` }
333+
334+ ${ showFiles && latestCommit && html `
335+ < div class ="latest-commit ">
336+ < span class ="commit-author "> ${ latestCommit . author } </ span >
337+ < span class ="commit-msg "> ${ latestCommit . message } </ span >
338+ < span class ="oid "> ${ latestCommit . oid . slice ( 0 , 8 ) } </ span >
339+ < span class ="meta "> ${ relativeTime ( latestCommit . timestamp ) } </ span >
340+ </ div >
341+ ` }
342+
343+ ${ showFiles && tree && tree . length > 0 && html `
344+ < ul class ="file-list ">
345+ ${ tree . map ( ( e ) => html `
346+ < li >
347+ < span class ="file-icon "> ${ e . type === 'tree' ? '\u{1F4C1}' : '\u{1F4C4}' } </ span >
348+ ${ e . type === 'blob'
349+ ? html `< a href ="?repo=${ encodeURIComponent ( url ) } &path= ${ encodeURIComponent ( e . path ) } " onClick =${ ( ev ) => onFileClick ( ev , e . path , e . type ) } > ${ e . path } </ a > `
350+ : html `< span > ${ e . path } </ span > `
351+ }
352+ </ li >
353+ ` ) }
354+ </ ul >
355+ ` }
356+
357+ ${ showFiles && readmeHtml && html `
358+ < h2 > README</ h2 >
359+ < div class ="readme " dangerouslySetInnerHTML =${ { __html : readmeHtml } } > </ div >
360+ ` }
361+
362+ ${ showCommits && commitsLoading && html `< p class ="loading "> Loading commits…</ p > ` }
363+ ${ showCommits && commits && commits . length > 0 && html `
364+ < ul class ="commit-list ">
365+ ${ commits . map ( ( c ) => html `
366+ < li class ="commit ">
367+ < div class ="commit-message "> ${ c . commit . message . split ( '\n' ) [ 0 ] } </ div >
368+ < div class ="commit-meta ">
369+ < span class ="commit-author "> ${ c . commit . author . name } </ span >
370+ < span > committed ${ relativeTime ( c . commit . author . timestamp ) } </ span >
371+ < span class ="oid "> ${ c . oid . slice ( 0 , 8 ) } </ span >
372+ </ div >
373+ </ li >
374+ ` ) }
375+ </ ul >
376+ ` }
377+ ${ showCommits && commits && commits . length === 0 && html `< p class ="meta "> No commits.</ p > ` }
378+ </ div >
387379
388- ${ showCommits && commits && commits . length === 0 && html `< p class ="meta "> No commits.</ p > ` }
389-
390- ${ refs && refs . length > 0 && ! fileView && view === 'files' && html `
391- < details style ="margin-top: 1.5rem; ">
392- < summary > Refs (${ refs . length } )</ summary >
393- < ul class ="ref-list ">
394- ${ refs . map ( ( r ) => html `
395- < li >
396- < span > ${ r . ref } </ span >
397- < span class ="oid "> ${ r . oid ?. slice ( 0 , 8 ) || '' } </ span >
398- </ li >
399- ` ) }
400- </ ul >
401- </ details >
380+ < aside class ="sidebar ">
381+ < h3 > About</ h3 >
382+ < p class ="sidebar-desc "> A repository hosted on a Solid pod.</ p >
383+ < p class ="sidebar-link "> < a href =${ url } target ="_blank" rel="noopener"> ${ url } </ a > </ p >
384+ < ul class ="sidebar-stats ">
385+ ${ branch && html `< li > < span class ="stat-label "> Branch</ span > < code > ${ branch } </ code > </ li > ` }
386+ ${ refs && html `< li > < span class ="stat-label "> Refs</ span > ${ refs . length } </ li > ` }
387+ ${ commits && html `< li > < span class ="stat-label "> Commits</ span > ${ commits . length } +</ li > ` }
388+ ${ tree && html `< li > < span class ="stat-label "> Files (root)</ span > ${ tree . length } </ li > ` }
389+ </ ul >
390+ </ aside >
391+ </ div >
402392 ` }
403393
404394 ${ refs && refs . length === 0 && html `< p class ="meta "> No refs found (empty repo).</ p > ` }
0 commit comments