@@ -5,6 +5,7 @@ package repo
55
66import  (
77	"net/http" 
8+ 	"strings" 
89
910	pull_model "code.gitea.io/gitea/models/pull" 
1011	"code.gitea.io/gitea/modules/base" 
@@ -57,34 +58,85 @@ func isExcludedEntry(entry *git.TreeEntry) bool {
5758	return  false 
5859}
5960
60- type  FileDiffFile  struct  {
61- 	Name         string 
61+ // WebDiffFileItem is used by frontend, check the field names in frontend before changing 
62+ type  WebDiffFileItem  struct  {
63+ 	FullName     string 
64+ 	DisplayName  string 
6265	NameHash     string 
63- 	IsSubmodule  bool 
66+ 	DiffStatus   string 
67+ 	EntryMode    string 
6468	IsViewed     bool 
65- 	Status       string 
69+ 	Children     []* WebDiffFileItem 
70+ 	// TODO: add icon support in the future 
6671}
6772
68- // transformDiffTreeForUI transforms a DiffTree into a slice of FileDiffFile for UI rendering 
73+ // WebDiffFileTree is used by frontend, check the field names in frontend before changing 
74+ type  WebDiffFileTree  struct  {
75+ 	TreeRoot  WebDiffFileItem 
76+ }
77+ 
78+ // transformDiffTreeForWeb transforms a gitdiff.DiffTree into a WebDiffFileTree for Web UI rendering 
6979// it also takes a map of file names to their viewed state, which is used to mark files as viewed 
70- func  transformDiffTreeForUI (diffTree  * gitdiff.DiffTree , filesViewedState  map [string ]pull_model.ViewedState ) []FileDiffFile  {
71- 	files  :=  make ([]FileDiffFile , 0 , len (diffTree .Files ))
80+ func  transformDiffTreeForWeb (diffTree  * gitdiff.DiffTree , filesViewedState  map [string ]pull_model.ViewedState ) (dft  WebDiffFileTree ) {
81+ 	dirNodes  :=  map [string ]* WebDiffFileItem {"" : & dft .TreeRoot }
82+ 	addItem  :=  func (item  * WebDiffFileItem ) {
83+ 		var  parentPath  string 
84+ 		pos  :=  strings .LastIndexByte (item .FullName , '/' )
85+ 		if  pos  ==  - 1  {
86+ 			item .DisplayName  =  item .FullName 
87+ 		} else  {
88+ 			parentPath  =  item .FullName [:pos ]
89+ 			item .DisplayName  =  item .FullName [pos + 1 :]
90+ 		}
91+ 		parentNode , parentExists  :=  dirNodes [parentPath ]
92+ 		if  ! parentExists  {
93+ 			parentNode  =  & dft .TreeRoot 
94+ 			fields  :=  strings .Split (parentPath , "/" )
95+ 			for  idx , field  :=  range  fields  {
96+ 				nodePath  :=  strings .Join (fields [:idx + 1 ], "/" )
97+ 				node , ok  :=  dirNodes [nodePath ]
98+ 				if  ! ok  {
99+ 					node  =  & WebDiffFileItem {EntryMode : "tree" , DisplayName : field , FullName : nodePath }
100+ 					dirNodes [nodePath ] =  node 
101+ 					parentNode .Children  =  append (parentNode .Children , node )
102+ 				}
103+ 				parentNode  =  node 
104+ 			}
105+ 		}
106+ 		parentNode .Children  =  append (parentNode .Children , item )
107+ 	}
72108
73109	for  _ , file  :=  range  diffTree .Files  {
74- 		nameHash  :=  git .HashFilePathForWebUI (file .HeadPath )
75- 		isSubmodule  :=  file .HeadMode  ==  git .EntryModeCommit 
76- 		isViewed  :=  filesViewedState [file .HeadPath ] ==  pull_model .Viewed 
77- 
78- 		files  =  append (files , FileDiffFile {
79- 			Name :        file .HeadPath ,
80- 			NameHash :    nameHash ,
81- 			IsSubmodule : isSubmodule ,
82- 			IsViewed :    isViewed ,
83- 			Status :      file .Status ,
84- 		})
110+ 		item  :=  & WebDiffFileItem {FullName : file .HeadPath , DiffStatus : file .Status }
111+ 		item .IsViewed  =  filesViewedState [item .FullName ] ==  pull_model .Viewed 
112+ 		item .NameHash  =  git .HashFilePathForWebUI (item .FullName )
113+ 
114+ 		switch  file .HeadMode  {
115+ 		case  git .EntryModeTree :
116+ 			item .EntryMode  =  "tree" 
117+ 		case  git .EntryModeCommit :
118+ 			item .EntryMode  =  "commit"  // submodule 
119+ 		default :
120+ 			// default to empty, and will be treated as "blob" file because there is no "symlink" support yet 
121+ 		}
122+ 		addItem (item )
85123	}
86124
87- 	return  files 
125+ 	var  mergeSingleDir  func (node  * WebDiffFileItem )
126+ 	mergeSingleDir  =  func (node  * WebDiffFileItem ) {
127+ 		if  len (node .Children ) ==  1  {
128+ 			if  child  :=  node .Children [0 ]; child .EntryMode  ==  "tree"  {
129+ 				node .FullName  =  child .FullName 
130+ 				node .DisplayName  =  node .DisplayName  +  "/"  +  child .DisplayName 
131+ 				node .Children  =  child .Children 
132+ 				mergeSingleDir (node )
133+ 			}
134+ 		}
135+ 	}
136+ 	for  _ , node  :=  range  dft .TreeRoot .Children  {
137+ 		mergeSingleDir (node )
138+ 	}
139+ 	return  dft 
88140}
89141
90142func  TreeViewNodes (ctx  * context.Context ) {
0 commit comments