@@ -22,19 +22,21 @@ import (
2222	git_model "code.gitea.io/gitea/models/git" 
2323	issues_model "code.gitea.io/gitea/models/issues" 
2424	pull_model "code.gitea.io/gitea/models/pull" 
25- 	repo_model "code.gitea.io/gitea/models/repo" 
2625	user_model "code.gitea.io/gitea/models/user" 
2726	"code.gitea.io/gitea/modules/analyze" 
27+ 	"code.gitea.io/gitea/modules/base" 
2828	"code.gitea.io/gitea/modules/charset" 
2929	"code.gitea.io/gitea/modules/git" 
3030	"code.gitea.io/gitea/modules/git/attribute" 
3131	"code.gitea.io/gitea/modules/git/gitcmd" 
3232	"code.gitea.io/gitea/modules/gitrepo" 
3333	"code.gitea.io/gitea/modules/highlight" 
34+ 	"code.gitea.io/gitea/modules/htmlutil" 
3435	"code.gitea.io/gitea/modules/lfs" 
3536	"code.gitea.io/gitea/modules/log" 
3637	"code.gitea.io/gitea/modules/optional" 
3738	"code.gitea.io/gitea/modules/setting" 
39+ 	"code.gitea.io/gitea/modules/svg" 
3840	"code.gitea.io/gitea/modules/translation" 
3941	"code.gitea.io/gitea/modules/util" 
4042
@@ -67,28 +69,15 @@ const (
6769	DiffFileCopy 
6870)
6971
70- // DiffLineExpandDirection represents the DiffLineSection expand direction 
71- type  DiffLineExpandDirection  uint8 
72- 
73- // DiffLineExpandDirection possible values. 
74- const  (
75- 	DiffLineExpandNone  DiffLineExpandDirection  =  iota  +  1 
76- 	DiffLineExpandSingle 
77- 	DiffLineExpandUpDown 
78- 	DiffLineExpandUp 
79- 	DiffLineExpandDown 
80- )
81- 
8272// DiffLine represents a line difference in a DiffSection. 
8373type  DiffLine  struct  {
84- 	LeftIdx           int  // line number, 1-based 
85- 	RightIdx          int  // line number, 1-based 
86- 	Match             int  // the diff matched index. -1: no match. 0: plain and no need to match. >0: for add/del, "Lines" slice index of the other side 
87- 	Type              DiffLineType 
88- 	Content           string 
89- 	Comments          issues_model.CommentList  // related PR code comments 
90- 	SectionInfo       * DiffLineSectionInfo 
91- 	HiddenCommentIDs  []int64  // IDs of hidden comments in this section 
74+ 	LeftIdx      int  // line number, 1-based 
75+ 	RightIdx     int  // line number, 1-based 
76+ 	Match        int  // the diff matched index. -1: no match. 0: plain and no need to match. >0: for add/del, "Lines" slice index of the other side 
77+ 	Type         DiffLineType 
78+ 	Content      string 
79+ 	Comments     issues_model.CommentList  // related PR code comments 
80+ 	SectionInfo  * DiffLineSectionInfo 
9281}
9382
9483// DiffLineSectionInfo represents diff line section meta data 
@@ -100,6 +89,9 @@ type DiffLineSectionInfo struct {
10089	RightIdx       int 
10190	LeftHunkSize   int 
10291	RightHunkSize  int 
92+ 
93+ 	HiddenCommentIDs  []int64  // IDs of hidden comments in this section 
94+ 
10395}
10496
10597// DiffHTMLOperation is the HTML version of diffmatchpatch.Diff 
@@ -154,8 +146,7 @@ func (d *DiffLine) GetLineTypeMarker() string {
154146	return  "" 
155147}
156148
157- // GetBlobExcerptQuery builds query string to get blob excerpt 
158- func  (d  * DiffLine ) GetBlobExcerptQuery () string  {
149+ func  (d  * DiffLine ) getBlobExcerptQuery () string  {
159150	query  :=  fmt .Sprintf (
160151		"last_left=%d&last_right=%d&" + 
161152			"left=%d&right=%d&" + 
@@ -168,25 +159,70 @@ func (d *DiffLine) GetBlobExcerptQuery() string {
168159	return  query 
169160}
170161
171- // GetExpandDirection gets DiffLineExpandDirection 
172- func  (d  * DiffLine ) GetExpandDirection () DiffLineExpandDirection  {
162+ func  (d  * DiffLine ) getExpandDirection () string  {
173163	if  d .Type  !=  DiffLineSection  ||  d .SectionInfo  ==  nil  ||  d .SectionInfo .LeftIdx - d .SectionInfo .LastLeftIdx  <=  1  ||  d .SectionInfo .RightIdx - d .SectionInfo .LastRightIdx  <=  1  {
174- 		return  DiffLineExpandNone 
164+ 		return  "" 
175165	}
176166	if  d .SectionInfo .LastLeftIdx  <=  0  &&  d .SectionInfo .LastRightIdx  <=  0  {
177- 		return  DiffLineExpandUp 
167+ 		return  "up" 
178168	} else  if  d .SectionInfo .RightIdx - d .SectionInfo .LastRightIdx  >  BlobExcerptChunkSize  &&  d .SectionInfo .RightHunkSize  >  0  {
179- 		return  DiffLineExpandUpDown 
169+ 		return  "updown" 
180170	} else  if  d .SectionInfo .LeftHunkSize  <=  0  &&  d .SectionInfo .RightHunkSize  <=  0  {
181- 		return  DiffLineExpandDown 
171+ 		return  "down" 
182172	}
183- 	return  DiffLineExpandSingle 
173+ 	return  "single" 
184174}
185175
186- // CalculateHiddenCommentIDsForLine finds comment IDs that are in the hidden range of an expand button 
187- func  CalculateHiddenCommentIDsForLine (line  * DiffLine , lineComments  map [int64 ][]* issues_model.Comment ) []int64  {
188- 	if  line .Type  !=  DiffLineSection  ||  line .SectionInfo  ==  nil  {
189- 		return  nil 
176+ type  DiffBlobExcerptData  struct  {
177+ 	BaseLink       string 
178+ 	IsWikiRepo     bool 
179+ 	PullIndex      int64 
180+ 	DiffStyle      string 
181+ 	AfterCommitID  string 
182+ }
183+ 
184+ func  (d  * DiffLine ) RenderBlobExcerptButtons (fileNameHash  string , data  * DiffBlobExcerptData ) template.HTML  {
185+ 	dataHiddenCommentIDs  :=  strings .Join (base .Int64sToStrings (d .SectionInfo .HiddenCommentIDs ), "," )
186+ 	anchor  :=  fmt .Sprintf ("diff-%sK%d" , fileNameHash , d .SectionInfo .RightIdx )
187+ 
188+ 	makeButton  :=  func (direction , svgName  string ) template.HTML  {
189+ 		style  :=  util .IfZero (data .DiffStyle , "unified" )
190+ 		link  :=  data .BaseLink  +  "/"  +  data .AfterCommitID  +  fmt .Sprintf ("?style=%s&direction=%s&anchor=%s" , url .QueryEscape (style ), direction , url .QueryEscape (anchor ))
191+ 		if  data .PullIndex  >  0  {
192+ 			link  +=  fmt .Sprintf ("&is_pull=1&issue_index=%d" , data .PullIndex )
193+ 		}
194+ 		link  +=  "&"  +  d .getBlobExcerptQuery ()
195+ 
196+ 		svgContent  :=  svg .RenderHTML (svgName )
197+ 		return  htmlutil .HTMLFormat (
198+ 			`<button class="code-expander-button" hx-target="closest tr" hx-get="%s"  data-hidden-comment-ids="%s">%s</button>` ,
199+ 			link , dataHiddenCommentIDs , svgContent ,
200+ 		)
201+ 	}
202+ 	var  content  template.HTML 
203+ 
204+ 	if  len (d .SectionInfo .HiddenCommentIDs ) >  0  {
205+ 		tooltip  :=  fmt .Sprintf ("%d hidden comment(s)" , len (d .SectionInfo .HiddenCommentIDs ))
206+ 		content  +=  htmlutil .HTMLFormat (`<span class="code-comment-more" data-tooltip-content="%s">%d</span>` , tooltip , len (d .SectionInfo .HiddenCommentIDs ))
207+ 	}
208+ 
209+ 	expandDirection  :=  d .getExpandDirection ()
210+ 	if  expandDirection  ==  "up"  ||  expandDirection  ==  "updown"  {
211+ 		content  +=  makeButton ("up" , "octicon-fold-up" )
212+ 	}
213+ 	if  expandDirection  ==  "updown"  ||  expandDirection  ==  "down"  {
214+ 		content  +=  makeButton ("down" , "octicon-fold-down" )
215+ 	}
216+ 	if  expandDirection  ==  "single"  {
217+ 		content  +=  makeButton ("single" , "octicon-fold" )
218+ 	}
219+ 	return  htmlutil .HTMLFormat (`<div class="code-expander-buttons" data-expand-direction="%s">%s</div>` , expandDirection , content )
220+ }
221+ 
222+ // FillHiddenCommentIDsForDiffLine finds comment IDs that are in the hidden range of an expand button 
223+ func  FillHiddenCommentIDsForDiffLine (line  * DiffLine , lineComments  map [int64 ][]* issues_model.Comment ) {
224+ 	if  line .Type  !=  DiffLineSection  {
225+ 		return 
190226	}
191227
192228	var  hiddenCommentIDs  []int64 
@@ -196,13 +232,13 @@ func CalculateHiddenCommentIDsForLine(line *DiffLine, lineComments map[int64][]*
196232			absLineNum  =  int (- commentLineNum )
197233		}
198234		// Check if comments are in the hidden range 
199- 		if  absLineNum  >  line .SectionInfo .LastRightIdx  &&  absLineNum  <  line .SectionInfo .RightIdx  {
235+ 		if  absLineNum  >  line .SectionInfo .LastRightIdx  &&  absLineNum  <=   line .SectionInfo .RightIdx  {
200236			for  _ , comment  :=  range  comments  {
201237				hiddenCommentIDs  =  append (hiddenCommentIDs , comment .ID )
202238			}
203239		}
204240	}
205- 	return  hiddenCommentIDs 
241+ 	line . SectionInfo . HiddenCommentIDs   =  hiddenCommentIDs 
206242}
207243
208244func  getDiffLineSectionInfo (treePath , line  string , lastLeftIdx , lastRightIdx  int ) * DiffLineSectionInfo  {
@@ -508,11 +544,8 @@ func (diff *Diff) LoadComments(ctx context.Context, issue *issues_model.Issue, c
508544					sort .SliceStable (line .Comments , func (i , j  int ) bool  {
509545						return  line .Comments [i ].CreatedUnix  <  line .Comments [j ].CreatedUnix 
510546					})
511- 
512547					// Mark expand buttons that have comments in hidden lines 
513- 					if  hiddenIDs  :=  CalculateHiddenCommentIDsForLine (line , lineCommits ); len (hiddenIDs ) >  0  {
514- 						line .HiddenCommentIDs  =  hiddenIDs 
515- 					}
548+ 					FillHiddenCommentIDsForDiffLine (line , lineCommits )
516549				}
517550			}
518551		}
@@ -1309,7 +1342,7 @@ type DiffShortStat struct {
13091342	NumFiles , TotalAddition , TotalDeletion  int 
13101343}
13111344
1312- func  GetDiffShortStat (ctx  context.Context , repo   * repo_model .Repository , gitRepo  * git.Repository , beforeCommitID , afterCommitID  string ) (* DiffShortStat , error ) {
1345+ func  GetDiffShortStat (ctx  context.Context , repoStorage  gitrepo .Repository , gitRepo  * git.Repository , beforeCommitID , afterCommitID  string ) (* DiffShortStat , error ) {
13131346	afterCommit , err  :=  gitRepo .GetCommit (afterCommitID )
13141347	if  err  !=  nil  {
13151348		return  nil , err 
@@ -1321,7 +1354,7 @@ func GetDiffShortStat(ctx context.Context, repo *repo_model.Repository, gitRepo
13211354	}
13221355
13231356	diff  :=  & DiffShortStat {}
1324- 	diff .NumFiles , diff .TotalAddition , diff .TotalDeletion , err  =  gitrepo .GetDiffShortStatByCmdArgs (ctx , repo , nil , actualBeforeCommitID .String (), afterCommitID )
1357+ 	diff .NumFiles , diff .TotalAddition , diff .TotalDeletion , err  =  gitrepo .GetDiffShortStatByCmdArgs (ctx , repoStorage , nil , actualBeforeCommitID .String (), afterCommitID )
13251358	if  err  !=  nil  {
13261359		return  nil , err 
13271360	}
0 commit comments