From f0710c5838d68c8fe753b271bff8cb0d859b948c Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 2 Mar 2024 12:44:03 +0000 Subject: [PATCH 1/5] Fix elipsis button not working if the last commit loading is deferred Before this change, if we had more than 200 entries being deferred in loading, the entire table would get replaced thus losing any event listeners attached to the elements within the table, such as the elipsis button and commit list with tippy. With this change we remove the previous javascript code that replaced the table and use htmx to replace the table. htmx attributes added: - `hx-indicator="tr.notready td.message span"`: attach the loading spinner to the files whose last commit is still being loaded - `hx-trigger="load[this.querySelectorAll('tr.notready').length > 0]"` trigger the request-replace behavior as soon as possible and only if the current table is showing files that haven't had their latest commit info loaded. If this inline javascript doesn't look good I can change it so the backend doesn't render the htmx attributes if it's an htmx request, and the trigger would simply be `load` but I like it as it is now - `hx-swap="morph"`: use the idiomorph morphing algorithm, this is the thing that makes it so the elipsis button event listener is kept during the replacement, fixing the bug - `hx-post="{{.LastCommitLoaderURL}}"`: make a post request to this url to get the table with all of the commit information As part of this change I removed the handling of partial replacement in the case we have less than 200 "not ready" files. The first reason is that I couldn't make htmx replace only a subset of returned elements, the second reason is that we have a cache implemented in the backend already so the only cost added is that we query the cache a few times (which is sure to be populated due to the initial request), and the last reason is that since the last refactor of this functionality that removed jQuery we don't properly send the "not ready" entries as the backend expects `FormData` with `f[]` and we send a JSON with `f` so we always query for all rows anyway. Signed-off-by: Yarden Shoham --- routers/web/repo/view.go | 16 +---------- templates/repo/view_list.tmpl | 2 +- web_src/js/features/repo-commit.js | 43 ------------------------------ web_src/js/index.js | 7 +---- 4 files changed, 3 insertions(+), 65 deletions(-) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index e89739e2fb6d..7c218e66f815 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -35,7 +35,6 @@ import ( "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/lfs" @@ -859,21 +858,8 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri defer cancel() } - selected := make(container.Set[string]) - selected.AddMultiple(ctx.FormStrings("f[]")...) - - entries := allEntries - if len(selected) > 0 { - entries = make(git.Entries, 0, len(selected)) - for _, entry := range allEntries { - if selected.Contains(entry.Name()) { - entries = append(entries, entry) - } - } - } - var latestCommit *git.Commit - ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(commitInfoCtx, ctx.Repo.Commit, ctx.Repo.TreePath) + ctx.Data["Files"], latestCommit, err = allEntries.GetCommitsInfo(commitInfoCtx, ctx.Repo.Commit, ctx.Repo.TreePath) if err != nil { ctx.ServerError("GetCommitsInfo", err) return nil diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index c1ef4ff4cb0e..bebd3224c4bd 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -1,4 +1,4 @@ - +
rows in response (eg: ) - // at the moment only the "data-entryname" rows should be processed - const entryName = row.getAttribute('data-entryname'); - if (entryName) { - entryMap[entryName]?.replaceWith(row); - } - } -} - export function initCommitStatuses() { for (const element of document.querySelectorAll('[data-tippy="commit-statuses"]')) { const top = document.querySelector('.repository.file.list') || document.querySelector('.repository.diff'); diff --git a/web_src/js/index.js b/web_src/js/index.js index b7f3ba99a0e9..c7eac9d24273 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -33,11 +33,7 @@ import { initRepoPullRequestAllowMaintainerEdit, initRepoPullRequestReview, initRepoIssueSidebarList, initArchivedLabelHandler, } from './features/repo-issue.js'; -import { - initRepoEllipsisButton, - initRepoCommitLastCommitLoader, - initCommitStatuses, -} from './features/repo-commit.js'; +import {initRepoEllipsisButton, initCommitStatuses} from './features/repo-commit.js'; import { initFootLanguageMenu, initGlobalButtonClickOnEnter, @@ -148,7 +144,6 @@ onDomReady(() => { initRepoCommentForm(); initRepoEllipsisButton(); initRepoDiffCommitBranchesAndTags(); - initRepoCommitLastCommitLoader(); initRepoEditor(); initRepoGraphGit(); initRepoIssueContentHistory(); From 0f5d7d96301f71d56b9c1167164edae1e942bd8a Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 2 Mar 2024 15:47:42 +0000 Subject: [PATCH 2/5] Check before applying htmx attributes --- routers/web/repo/view.go | 9 +++++++-- templates/repo/view_list.tmpl | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 7c218e66f815..58e84fd90759 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -858,12 +858,17 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri defer cancel() } - var latestCommit *git.Commit - ctx.Data["Files"], latestCommit, err = allEntries.GetCommitsInfo(commitInfoCtx, ctx.Repo.Commit, ctx.Repo.TreePath) + files, latestCommit, err := allEntries.GetCommitsInfo(commitInfoCtx, ctx.Repo.Commit, ctx.Repo.TreePath) if err != nil { ctx.ServerError("GetCommitsInfo", err) return nil } + ctx.Data["Files"] = files + for _, f := range files { + if f.Commit == nil { + ctx.Data["HasFilesWithoutLatestCommit"] = true + } + } if !loadLatestCommitData(ctx, latestCommit) { return nil diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index bebd3224c4bd..d421a74004c4 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -1,4 +1,4 @@ -
diff --git a/web_src/js/features/repo-commit.js b/web_src/js/features/repo-commit.js index 7e2f6fa58ead..f61ea08a42b6 100644 --- a/web_src/js/features/repo-commit.js +++ b/web_src/js/features/repo-commit.js @@ -1,7 +1,5 @@ import {createTippy} from '../modules/tippy.js'; import {toggleElem} from '../utils/dom.js'; -import {parseDom} from '../utils.js'; -import {POST} from '../modules/fetch.js'; export function initRepoEllipsisButton() { for (const button of document.querySelectorAll('.js-toggle-commit-body')) { @@ -14,47 +12,6 @@ export function initRepoEllipsisButton() { } } -export async function initRepoCommitLastCommitLoader() { - const entryMap = {}; - - const entries = Array.from(document.querySelectorAll('table#repo-files-table tr.notready'), (el) => { - const entryName = el.getAttribute('data-entryname'); - entryMap[entryName] = el; - return entryName; - }); - - if (entries.length === 0) { - return; - } - - const lastCommitLoaderURL = document.querySelector('table#repo-files-table').getAttribute('data-last-commit-loader-url'); - - if (entries.length > 200) { - // For more than 200 entries, replace the entire table - const response = await POST(lastCommitLoaderURL); - const data = await response.text(); - document.querySelector('table#repo-files-table').outerHTML = data; - return; - } - - // For fewer entries, update individual rows - const response = await POST(lastCommitLoaderURL, {data: {'f': entries}}); - const data = await response.text(); - const doc = parseDom(data, 'text/html'); - for (const row of doc.querySelectorAll('tr')) { - if (row.className === 'commit-list') { - document.querySelector('table#repo-files-table .commit-list')?.replaceWith(row); - continue; - } - // there are other
+
From b6e65a76d313f9df9d113d556690129b660690cb Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 2 Mar 2024 17:57:39 +0200 Subject: [PATCH 3/5] Update routers/web/repo/view.go Co-authored-by: wxiaoguang --- routers/web/repo/view.go | 1 + 1 file changed, 1 insertion(+) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 58e84fd90759..4df10fbea1ad 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -867,6 +867,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri for _, f := range files { if f.Commit == nil { ctx.Data["HasFilesWithoutLatestCommit"] = true + break } } From 09efb7abf6c34f46d0bb7b71c84f98b1caa9ba63 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 2 Mar 2024 17:59:06 +0200 Subject: [PATCH 4/5] Update templates/repo/view_list.tmpl Co-authored-by: wxiaoguang --- templates/repo/view_list.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index d421a74004c4..73825c2bd5fb 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -1,7 +1,7 @@ - From 8bd082ba34efb3477d9473b6fa62ec1e6a7620b5 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 2 Mar 2024 16:29:06 +0000 Subject: [PATCH 5/5] Remove the ... --- templates/repo/view_list.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index 73825c2bd5fb..988a5ddd50e8 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -55,7 +55,7 @@ {{$commitLink := printf "%s/commit/%s" $.RepoLink (PathEscape $commit.ID.String)}} {{RenderCommitMessageLinkSubject $.Context $commit.Message $commitLink ($.Repository.ComposeMetas ctx)}} {{else}} -
+
{{end}}
+ {{template "repo/latest_commit" .}} {{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When ctx.Locale}}{{end}}{{end}}