diff --git a/config.yaml b/config.yaml index d8f4d00..dc909fc 100644 --- a/config.yaml +++ b/config.yaml @@ -70,6 +70,21 @@ ui: # Number of commits to display in a single "Commits" (log) page. commitsPageSize: 30 + diff: + # When a total line count of added and deleted lines exceeds this value, + # default UI hides diff view for the file and displays an interactive + # element to reveal the diff lazily. + # + # Displaying large diffs slows browser's rendering process down significantly. + # This option prevents surprising slow loading: user may not know the commit + # contains large diffs prior to visit. + # + # The does not affect server load for large diffs. For server-side diff + # generation performance, see "repo.diff" config option. + # + # Setting 0 disables the hiding mechanism. Default value is 0. + hideThresholdLines: 1000 + # You can set repository's category by creating `category` file in $GIT_DIR or # setting `gitweb.category` git config. # https://git-scm.com/docs/gitweb#Documentation/gitweb.txt-categoryorgitwebcategory diff --git a/config/config.go b/config/config.go index 6f7f848..2eb83a4 100644 --- a/config/config.go +++ b/config/config.go @@ -35,7 +35,12 @@ type Config struct { } `yaml:"meta"` UI struct { CommitsPageSize uint32 `yaml:"commitsPageSize"` - Category struct { + Diff struct { + // HideThresholdLines controls threshold to hide diff for the file. + // Unit is line count, and set 0 to disable diff hiding at all. + HideThresholdLines uint32 `yaml:"hideThresholdLines"` + } + Category struct { Grouping bool `yaml:"grouping"` Default string `yaml:"default"` Order []string `yaml:"order"` diff --git a/demo/config.yaml b/demo/config.yaml index f8ea6e6..39641f7 100644 --- a/demo/config.yaml +++ b/demo/config.yaml @@ -47,6 +47,9 @@ ui: - "Mirror" - "Abandoned" + diff: + hideThresholdLines: 1000 + footer: links: - text: Hosted diff --git a/embed/templates/repo-commit.html.tmpl b/embed/templates/repo-commit.html.tmpl index da4871c..7001dde 100644 --- a/embed/templates/repo-commit.html.tmpl +++ b/embed/templates/repo-commit.html.tmpl @@ -66,6 +66,10 @@ SPDX-License-Identifier: MIT {{ if .IsBinary -}}

Diff for binary file is unavailable.

{{- else -}} + {{- if $root.IsLargeDiff . -}} +
+ Diff ({{ $root.FileDiffStat . }}) + {{- end -}} + {{- if $root.IsLargeDiff . -}} +
+ {{- end -}} {{- end }} diff --git a/routes/data.go b/routes/data.go index 64486f8..9e1f303 100644 --- a/routes/data.go +++ b/routes/data.go @@ -6,10 +6,12 @@ package routes import ( + "fmt" "html/template" "maps" "slices" + "github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/pocka/legit/config" @@ -241,6 +243,33 @@ type repoCommitData struct { Diff *git.NiceDiff } +func (r repoCommitData) IsLargeDiff(file *gitdiff.File) bool { + if r.Config.UI.Diff.HideThresholdLines == 0 { + return false + } + + var n uint32 + + for _, fragment := range file.TextFragments { + n += uint32(max(0, fragment.LinesAdded)) + n += uint32(max(0, fragment.LinesDeleted)) + } + + return n > r.Config.UI.Diff.HideThresholdLines +} + +func (r repoCommitData) FileDiffStat(file *gitdiff.File) string { + var added int64 + var deleted int64 + + for _, fragment := range file.TextFragments { + added += fragment.LinesAdded + deleted += fragment.LinesDeleted + } + + return fmt.Sprintf("+%d/-%d", added, deleted) +} + // error404Data is a data object passed to "404" template. type error404Data struct { // Config represents a resolved config based on "config.yaml".