@@ -488,54 +488,61 @@ export const isHttpError = (error: unknown, status: number): boolean => {
488488 && error . status === status ;
489489}
490490
491-
492491/**
493- * Parses a URL path array to extract the full repository name and revision .
494- * This function assumes a URL structure like :
495- * `.../[hostname]/[ owner]/[ repo@revision]/-/tree/...`
496- * Or for nested groups (like GitLab):
497- * `.../[hostname]/[group]/[subgroup]/[ repo@revision]/-/tree/...`
492+ * Parses the URL path to generate a descriptive title .
493+ * It handles three cases :
494+ * 1. File view (`blob`): "filename.ts - owner/ repo"
495+ * 2. Directory view (`tree`): "directory/ - owner/repo"
496+ * 3. Repository root: "owner/ repo"
498497 *
499498 * @param path The array of path segments from Next.js params.
500- * @returns An object with fullRepoName and revision, or null if parsing fails .
499+ * @returns A formatted title string .
501500 */
502- export const parseRepoPath = ( path : string [ ] ) : { fullRepoName : string ; revision : string } | null => {
503- if ( path . length < 2 ) {
504- return null ; // Not enough path segments to parse.
505- }
506-
507- // Find the index of the `-` delimiter which separates the repo info from the file tree info.
501+ export const parsePathForTitle = ( path : string [ ] ) : string => {
508502 const delimiterIndex = path . indexOf ( '-' ) ;
509-
510- // If no delimiter is found, we can't reliably parse the path.
511- if ( delimiterIndex === - 1 ) {
512- return null ;
503+ if ( delimiterIndex === - 1 || delimiterIndex === 0 ) {
504+ return 'Browse' ;
513505 }
514506
515- // The repository parts are between the hostname (index 0) and the delimiter.
516- // e.g., ["github.com", "sourcebot-dev", "sourcebot"] -> slice will be ["sourcebot-dev", "sourcebot"]
517507 const repoParts = path . slice ( 1 , delimiterIndex ) ;
508+ if ( repoParts . length === 0 ) return 'Browse' ;
518509
519- if ( repoParts . length === 0 ) {
520- return null ;
521- }
510+ const lastPart = decodeURIComponent ( repoParts . pop ( ) ! ) ;
511+ const [ repoNamePart , revision = '' ] = lastPart . split ( '@' ) ;
512+ const ownerParts = repoParts ;
513+ const fullRepoName = [ ...ownerParts , repoNamePart ] . join ( '/' ) ;
514+ const repoAndRevision = `${ fullRepoName } ${ revision ? ` @ ${ revision } ` : '' } ` ;
522515
523- // The last part of the repo segment potentially contains the revision.
524- const lastPart = repoParts [ repoParts . length - 1 ] ;
516+ // Check for file (`blob`) or directory (`tree`) view
517+ const blobIndex = path . indexOf ( 'blob' ) ;
518+ const treeIndex = path . indexOf ( 'tree' ) ;
525519
526- // URL segments are encoded. Decode it to handle characters like '@' (%40).
527- const decodedLastPart = decodeURIComponent ( lastPart ) ;
520+ // Case 1: Viewing a file
521+ if ( blobIndex !== - 1 && path . length > blobIndex + 1 ) {
522+ const encodedFilePath = path [ blobIndex + 1 ] ;
523+ const filePath = decodeURIComponent ( encodedFilePath ) ;
528524
529- const [ repoNamePart , revision = '' ] = decodedLastPart . split ( '@' ) ;
525+ const fileName = filePath . split ( '/' ) . pop ( ) || filePath ;
526+
527+ // Return a title like: "agents.ts - sourcebot-dev/sourcebot @ HEAD"
528+ return `${ fileName } - ${ repoAndRevision } ` ;
529+ }
530530
531- // The preceding parts form the owner/group path.
532- // e.g., ["sourcebot"] or ["my-group", "my-subgroup"]
533- const ownerParts = repoParts . slice ( 0 , repoParts . length - 1 ) ;
531+ // Case 2: Viewing a directory
532+ if ( treeIndex !== - 1 && path . length > treeIndex + 1 ) {
533+ const encodedDirPath = path [ treeIndex + 1 ] ;
534+ const dirPath = decodeURIComponent ( encodedDirPath ) ;
535+
536+ // If we're at the root of the tree, just show the repo name
537+ if ( dirPath === '/' || dirPath === '' ) {
538+ return repoAndRevision ;
539+ }
534540
535- // Reconstruct the full repository name.
536- // e.g., "sourcebot-dev" + "/" + " sourcebot"
537- // e.g., "my-group/my-subgroup" + "/" + "my-repo"
538- const fullRepoName = [ ... ownerParts , repoNamePart ] . join ( '/' ) ;
541+ // Otherwise, show the directory path
542+ // Return a title like: "client/src/store/ - sourcebot-dev/sourcebot @ HEAD "
543+ return ` ${ dirPath . endsWith ( '/' ) ? dirPath : dirPath + '/' } - ${ repoAndRevision } ` ;
544+ }
539545
540- return { fullRepoName, revision } ;
546+ // Case 3: Fallback to the repository root
547+ return repoAndRevision ;
541548}
0 commit comments