aboutsummaryrefslogtreecommitdiffstats
path: root/routers/web/repo/treelist.go
diff options
context:
space:
mode:
Diffstat (limited to 'routers/web/repo/treelist.go')
-rw-r--r--routers/web/repo/treelist.go99
1 files changed, 78 insertions, 21 deletions
diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go
index ab74741e61..340b2bc091 100644
--- a/routers/web/repo/treelist.go
+++ b/routers/web/repo/treelist.go
@@ -4,10 +4,14 @@
package repo
import (
+ "html/template"
"net/http"
+ "path"
+ "strings"
pull_model "code.gitea.io/gitea/models/pull"
"code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/fileicon"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/gitdiff"
@@ -56,41 +60,94 @@ func isExcludedEntry(entry *git.TreeEntry) bool {
return false
}
-type FileDiffFile struct {
- Name string
+// WebDiffFileItem is used by frontend, check the field names in frontend before changing
+type WebDiffFileItem struct {
+ FullName string
+ DisplayName string
NameHash string
- IsSubmodule bool
+ DiffStatus string
+ EntryMode string
IsViewed bool
- Status string
+ Children []*WebDiffFileItem
+ FileIcon template.HTML
}
-// transformDiffTreeForUI transforms a DiffTree into a slice of FileDiffFile for UI rendering
+// WebDiffFileTree is used by frontend, check the field names in frontend before changing
+type WebDiffFileTree struct {
+ TreeRoot WebDiffFileItem
+}
+
+// transformDiffTreeForWeb transforms a gitdiff.DiffTree into a WebDiffFileTree for Web UI rendering
// it also takes a map of file names to their viewed state, which is used to mark files as viewed
-func transformDiffTreeForUI(diffTree *gitdiff.DiffTree, filesViewedState map[string]pull_model.ViewedState) []FileDiffFile {
- files := make([]FileDiffFile, 0, len(diffTree.Files))
+func transformDiffTreeForWeb(renderedIconPool *fileicon.RenderedIconPool, diffTree *gitdiff.DiffTree, filesViewedState map[string]pull_model.ViewedState) (dft WebDiffFileTree) {
+ dirNodes := map[string]*WebDiffFileItem{"": &dft.TreeRoot}
+ addItem := func(item *WebDiffFileItem) {
+ var parentPath string
+ pos := strings.LastIndexByte(item.FullName, '/')
+ if pos == -1 {
+ item.DisplayName = item.FullName
+ } else {
+ parentPath = item.FullName[:pos]
+ item.DisplayName = item.FullName[pos+1:]
+ }
+ parentNode, parentExists := dirNodes[parentPath]
+ if !parentExists {
+ parentNode = &dft.TreeRoot
+ fields := strings.Split(parentPath, "/")
+ for idx, field := range fields {
+ nodePath := strings.Join(fields[:idx+1], "/")
+ node, ok := dirNodes[nodePath]
+ if !ok {
+ node = &WebDiffFileItem{EntryMode: "tree", DisplayName: field, FullName: nodePath}
+ dirNodes[nodePath] = node
+ parentNode.Children = append(parentNode.Children, node)
+ }
+ parentNode = node
+ }
+ }
+ parentNode.Children = append(parentNode.Children, item)
+ }
for _, file := range diffTree.Files {
- nameHash := git.HashFilePathForWebUI(file.HeadPath)
- isSubmodule := file.HeadMode == git.EntryModeCommit
- isViewed := filesViewedState[file.HeadPath] == pull_model.Viewed
-
- files = append(files, FileDiffFile{
- Name: file.HeadPath,
- NameHash: nameHash,
- IsSubmodule: isSubmodule,
- IsViewed: isViewed,
- Status: file.Status,
- })
+ item := &WebDiffFileItem{FullName: file.HeadPath, DiffStatus: file.Status}
+ item.IsViewed = filesViewedState[item.FullName] == pull_model.Viewed
+ item.NameHash = git.HashFilePathForWebUI(item.FullName)
+ item.FileIcon = fileicon.RenderEntryIconHTML(renderedIconPool, &fileicon.EntryInfo{BaseName: path.Base(file.HeadPath), EntryMode: file.HeadMode})
+
+ switch file.HeadMode {
+ case git.EntryModeTree:
+ item.EntryMode = "tree"
+ case git.EntryModeCommit:
+ item.EntryMode = "commit" // submodule
+ default:
+ // default to empty, and will be treated as "blob" file because there is no "symlink" support yet
+ }
+ addItem(item)
}
- return files
+ var mergeSingleDir func(node *WebDiffFileItem)
+ mergeSingleDir = func(node *WebDiffFileItem) {
+ if len(node.Children) == 1 {
+ if child := node.Children[0]; child.EntryMode == "tree" {
+ node.FullName = child.FullName
+ node.DisplayName = node.DisplayName + "/" + child.DisplayName
+ node.Children = child.Children
+ mergeSingleDir(node)
+ }
+ }
+ }
+ for _, node := range dft.TreeRoot.Children {
+ mergeSingleDir(node)
+ }
+ return dft
}
func TreeViewNodes(ctx *context.Context) {
- results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path"))
+ renderedIconPool := fileicon.NewRenderedIconPool()
+ results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.RepoLink, renderedIconPool, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path"))
if err != nil {
ctx.ServerError("GetTreeViewNodes", err)
return
}
- ctx.JSON(http.StatusOK, map[string]any{"fileTreeNodes": results})
+ ctx.JSON(http.StatusOK, map[string]any{"fileTreeNodes": results, "renderedIconPool": renderedIconPool.IconSVGs})
}