11import {
2- reviewFileChapters ,
2+ reviewFileChapterIndex ,
33 reviewFileGroup ,
44 type ReviewFileGroup ,
55} from "@t3tools/shared/reviewFileClassification" ;
@@ -366,7 +366,7 @@ function PullRequestCodeTab({
366366 const commentsOnly = ! guideFallback && settings . pullRequestViewing . commentsOnly ;
367367 const hideReviewed = ! guideFallback && settings . pullRequestViewing . hideReviewed ;
368368 const groupByType = guideFallback || settings . pullRequestViewing . groupByType ;
369- const [ selectedChapter , setSelectedChapter ] = useState < ReviewFileGroup > ( "implementation " ) ;
369+ const [ selectedChapter , setSelectedChapter ] = useState < ReviewFileGroup > ( "code " ) ;
370370 const [ chapterRailOpen , setChapterRailOpen ] = useState ( false ) ;
371371 const canSetChapterViewed = useAtomValue (
372372 pullRequestEnvironment . setFilesViewed . permissionAtom ( environmentId ) ,
@@ -416,7 +416,7 @@ function PullRequestCodeTab({
416416 setFoldOverride ( null ) ;
417417 setVisibleCommitCount ( COMMIT_PAGE_SIZE ) ;
418418 setOrphansOpen ( false ) ;
419- setSelectedChapter ( "implementation " ) ;
419+ setSelectedChapter ( "code " ) ;
420420 setChapterRailOpen ( false ) ;
421421 setSliceState ( { key : scopeKey , cursor : null , slices : NO_SLICES } ) ;
422422 }
@@ -741,15 +741,34 @@ function PullRequestCodeTab({
741741 ( commentCounts . get ( path ) ?. unresolved ?? 0 ) > 0 ,
742742 ) ,
743743 ) ;
744- const chapters = groupByType
745- ? reviewFileChapters ( annotatedFiles , ( file ) => file . path , filteredFiles )
746- : [ ] ;
744+ const diffComplete =
745+ loadedSlices . length > 0 &&
746+ nextCursor === null &&
747+ ! diffQuery . isPending &&
748+ diffQuery . error === null ;
749+ const chapterIndex = reviewFileChapterIndex ( {
750+ completePaths :
751+ commit === null && viewedFilesStore === "host" && filesViewed . filePaths !== null
752+ ? filesViewed . filePaths
753+ : diffComplete && ! withheldContent
754+ ? filePaths
755+ : null ,
756+ loadedFiles : annotatedFiles ,
757+ visibleFiles : filteredFiles ,
758+ getPath : ( file ) => file . path ,
759+ } ) ;
760+ const chapters = groupByType ? chapterIndex . chapters : [ ] ;
747761 const chapterPosition = Math . max (
748762 0 ,
749763 chapters . findIndex ( ( chapter ) => chapter . id === selectedChapter ) ,
750764 ) ;
751765 const chapter = chapters [ chapterPosition ] ?? null ;
752- const chapterReviewComplete = nextCursor === null && ! diffQuery . isPending ;
766+ const chapterReviewComplete =
767+ chapterIndex . complete && ( ! filesViewedEnabled || ( filesViewed . ready && ! filesViewed . truncated ) ) ;
768+ const chapterCountsPending =
769+ filesViewed . error || filesViewed . truncated || diffQuery . error
770+ ? "File counts unavailable"
771+ : "Loading file counts…" ;
753772 const items = ( ( ) : CodeViewDiffItem < ReviewAnnotationGroup > [ ] =>
754773 ( chapter ?. visibleFiles ?? filteredFiles ) . map (
755774 ( { fileKey, path, fileDiff, annotations, annotationsVersion } ) => {
@@ -884,28 +903,41 @@ function PullRequestCodeTab({
884903 ) ;
885904 } ;
886905
906+ const setChapterViewed = ( paths : ReadonlyArray < string > , reviewed : boolean ) => {
907+ const selected = new Set ( paths ) ;
908+ const remaining = new Set ( paths ) ;
909+ for ( const file of annotatedFiles ) {
910+ if ( ! selected . has ( file . path ) ) continue ;
911+ setFileViewed ( file . fileKey , file . path , reviewed ) ;
912+ remaining . delete ( file . path ) ;
913+ }
914+ for ( const path of remaining ) setViewed ( path , reviewed ) ;
915+ } ;
887916 const chapterSummaries = chapters . map ( ( candidate , index ) => {
888917 const members = candidate . files ;
889- const reviewedCount = members . filter ( ( file ) => isFileViewed ( file . path ) ) . length ;
890- const stat = members . reduce (
891- ( total , file ) => {
892- const next = sourceFileStats . get ( file . fileKey ) ?? getDiffLineStat ( [ file . fileDiff ] ) ;
893- return {
894- additions : total . additions + next . additions ,
895- deletions : total . deletions + next . deletions ,
896- } ;
897- } ,
898- { additions : 0 , deletions : 0 } ,
899- ) ;
918+ const reviewedCount = members . filter ( isFileViewed ) . length ;
919+ const stat = annotatedFiles
920+ . filter ( ( file ) => reviewFileGroup ( file . path ) === candidate . id )
921+ . reduce (
922+ ( total , file ) => {
923+ const next = sourceFileStats . get ( file . fileKey ) ?? getDiffLineStat ( [ file . fileDiff ] ) ;
924+ return {
925+ additions : total . additions + next . additions ,
926+ deletions : total . deletions + next . deletions ,
927+ } ;
928+ } ,
929+ { additions : 0 , deletions : 0 } ,
930+ ) ;
900931 return {
901932 title : candidate . title ,
902933 reviewed : chapterReviewComplete && reviewedCount === members . length ,
903- stat,
934+ stat : diffComplete ? stat : null ,
904935 detail :
905936 index !== chapterPosition ? (
906937 < span >
907- { reviewedCount } of { members . length } files reviewed
908- { chapterReviewComplete ? "" : " (loaded)" }
938+ { chapterReviewComplete
939+ ? `${ reviewedCount } of ${ members . length } files reviewed`
940+ : chapterCountsPending }
909941 </ span >
910942 ) : null ,
911943 ...( filesViewed . enabled && canSetChapterViewed
@@ -915,7 +947,7 @@ function PullRequestCodeTab({
915947 fileCount : members . length ,
916948 disabled : ! chapterReviewComplete ,
917949 onSetReviewed : ( reviewed : boolean ) => {
918- for ( const file of members ) setFileViewed ( file . fileKey , file . path , reviewed ) ;
950+ setChapterViewed ( members , reviewed ) ;
919951 } ,
920952 } ,
921953 }
@@ -1734,29 +1766,28 @@ function PullRequestCodeTab({
17341766 ariaLabel = "Code review chapters"
17351767 chapters = { chapterSummaries . map ( ( summary , index ) => {
17361768 const members = chapters [ index ] ?. files ?? [ ] ;
1737- const reviewedCount = members . filter ( ( file ) => isFileViewed ( file . path ) ) . length ;
1769+ const reviewedCount = members . filter ( isFileViewed ) . length ;
17381770 return {
17391771 ...summary ,
17401772 selectedContent :
17411773 index === chapterPosition ? (
17421774 < div className = "flex min-w-0 flex-col gap-2 px-2 pb-2" >
1743- < ReviewChapterProgress
1744- reviewedCount = { reviewedCount }
1745- fileCount = { members . length }
1746- disabled = { ! chapterReviewComplete }
1747- onSetReviewed = {
1748- filesViewed . enabled && canSetChapterViewed
1749- ? ( reviewed ) => {
1750- for ( const file of members )
1751- setFileViewed ( file . fileKey , file . path , reviewed ) ;
1752- }
1753- : null
1754- }
1755- />
1775+ { chapterReviewComplete ? (
1776+ < ReviewChapterProgress
1777+ reviewedCount = { reviewedCount }
1778+ fileCount = { members . length }
1779+ disabled = { ! chapterReviewComplete }
1780+ onSetReviewed = {
1781+ filesViewed . enabled && canSetChapterViewed
1782+ ? ( reviewed ) => {
1783+ setChapterViewed ( members , reviewed ) ;
1784+ }
1785+ : null
1786+ }
1787+ />
1788+ ) : null }
17561789 { ! chapterReviewComplete ? (
1757- < p className = "text-xs text-muted-foreground" >
1758- Load all files to review this chapter.
1759- </ p >
1790+ < p className = "text-xs text-muted-foreground" > { chapterCountsPending } </ p >
17601791 ) : null }
17611792 { guideFallback ? (
17621793 < ul className = "flex min-w-0 flex-col gap-0.5" >
0 commit comments