Load mentionValues asynchronously (#36739)

Eliminate a few database queries on all issue and pull request pages by
moving mention autocomplete data to async JSON endpoints fetched
on-demand when the user types `@`.

See https://github.com/go-gitea/gitea/pull/36739#issuecomment-3963184858
for the full table of affected pages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
silverwind
2026-03-07 21:37:37 +01:00
committed by GitHub
parent f250138f57
commit 130e34994f
32 changed files with 363 additions and 161 deletions
-15
View File
@@ -16,21 +16,6 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
pageData: {{.PageData}},
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
enableTimeTracking: {{EnableTimetracking}},
{{if or .Participants .Assignees .MentionableTeams}}
mentionValues: Array.from(new Map([
{{- range .Participants -}}
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink ctx}}'}],
{{- end -}}
{{- range .Assignees -}}
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink ctx}}'}],
{{- end -}}
{{- range .MentionableTeams -}}
['{{$.MentionableTeamsOrg}}/{{.Name}}', {key: '{{$.MentionableTeamsOrg}}/{{.Name}}', value: '{{$.MentionableTeamsOrg}}/{{.Name}}', name: '{{$.MentionableTeamsOrg}}/{{.Name}}', avatar: '{{$.MentionableTeamsOrgAvatar}}'}],
{{- end -}}
]).values()),
{{else}}
mentionValues: [],
{{end}}
mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
{{/* this global i18n object should only contain general texts. for specialized texts, it should be provided inside the related modules by: (1) API response (2) HTML data-attribute (3) PageData */}}
i18n: {
+1 -1
View File
@@ -184,7 +184,7 @@
<div>
<h1>ComboMarkdownEditor</h1>
{{template "shared/combomarkdowneditor" dict "MarkdownPreviewContext" "/owner/path"}}
{{template "shared/combomarkdowneditor" dict "MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorGeneral nil)}}
</div>
<h1>Tailwind CSS Demo</h1>
+3 -4
View File
@@ -18,11 +18,10 @@
<div class="field">
<label>{{ctx.Locale.Tr "repo.projects.description"}}</label>
{{/* TODO: repo-level project and org-level project have different behaviors to render */}}
{{/* the "Repository" is nil when the project is org-level */}}
{{/* "Repository" is nil when the project is owner-level, "Org" can be nil when owner is indivdual user */}}
{{$markdownEditorContext := or (ctx.MiscUtils.MarkdownEditorComment $.Repository) (ctx.MiscUtils.MarkdownEditorGeneral $.ContextUser)}}
{{template "shared/combomarkdowneditor" (dict
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewContext" (Iif $.Repository "" .HomeLink)
"MarkdownPreviewMode" (Iif $.Repository "comment")
"MarkdownEditorContext" $markdownEditorContext
"TextareaName" "content"
"TextareaContent" .content
"TextareaPlaceholder" (ctx.Locale.Tr "repo.projects.description_placeholder")
+1 -2
View File
@@ -227,8 +227,7 @@
<div class="field">
{{template "shared/combomarkdowneditor" (dict
"CustomInit" true
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment $.Repository)
"TextareaName" "content"
"DropzoneParentContainer" ".ui.form"
)}}
+2 -3
View File
@@ -1,4 +1,4 @@
{{if and $.root.SignedUserID (not $.Repository.IsArchived)}}
{{if and ctx.RootData.SignedUserID (not ctx.RootData.Repository.IsArchived)}}
<form class="ui form {{if $.hidden}}tw-hidden comment-form{{end}}" action="{{$.root.Issue.Link}}/files/reviews/comments" method="post">
<input type="hidden" name="origin" value="{{if $.root.PageIsPullFiles}}diff{{else}}timeline{{end}}">
<input type="hidden" name="latest_commit_id" value="{{$.root.AfterCommitID}}">
@@ -11,8 +11,7 @@
<div class="field">
{{template "shared/combomarkdowneditor" (dict
"CustomInit" true
"MarkdownPreviewInRepo" $.root.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment ctx.RootData.Repository)
"TextareaName" "content"
"TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
"DropzoneParentContainer" "form"
+1 -2
View File
@@ -19,8 +19,7 @@
</div>
<div class="field">
{{template "shared/combomarkdowneditor" (dict
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment $.Repository)
"TextareaName" "content"
"TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.review.placeholder")
"DropzoneParentContainer" "form"
+1 -2
View File
@@ -6,8 +6,7 @@
<div class="field">
{{template "shared/combomarkdowneditor" (dict
"CustomInit" true
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment $.Repository)
"TextareaName" "content"
"TextareaContent" $textareaContent
"TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
+1 -2
View File
@@ -9,8 +9,7 @@
{{template "shared/combomarkdowneditor" (dict
"CustomInit" true
"ContainerClasses" "tw-hidden"
"MarkdownPreviewInRepo" $.root.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment ctx.RootData.Repository)
"TextareaContent" .item.Attributes.value
"TextareaPlaceholder" .item.Attributes.placeholder
"DropzoneParentContainer" ".combo-editor-dropzone"
+1 -2
View File
@@ -36,8 +36,7 @@
<div class="field">
<label>{{ctx.Locale.Tr "repo.milestones.desc"}}</label>
{{template "shared/combomarkdowneditor" (dict
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment $.Repository)
"TextareaName" "content"
"TextareaContent" .content
"TextareaPlaceholder" (ctx.Locale.Tr "repo.milestones.desc")
+1 -2
View File
@@ -147,8 +147,7 @@
<div class="field">
{{template "shared/combomarkdowneditor" (dict
"CustomInit" true
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment $.Repository)
"TextareaName" "content"
"DropzoneParentContainer" ".ui.form"
)}}
+1 -2
View File
@@ -69,8 +69,7 @@
</div>
<div class="field">
{{template "shared/combomarkdowneditor" (dict
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "comment"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorComment $.Repository)
"TextareaName" "content"
"TextareaContent" .content
"TextareaPlaceholder" (ctx.Locale.Tr "repo.release.message")
+1 -2
View File
@@ -23,8 +23,7 @@
{{end}}
{{template "shared/combomarkdowneditor" (dict
"CustomInit" true
"MarkdownPreviewInRepo" $.Repository
"MarkdownPreviewMode" "wiki"
"MarkdownEditorContext" (ctx.MiscUtils.MarkdownEditorWiki $.Repository)
"TextareaName" "content"
"TextareaContent" $content
"TextareaPlaceholder" (ctx.Locale.Tr "repo.wiki.page_content")
+9 -12
View File
@@ -2,9 +2,7 @@
* CustomInit: do not initialize the editor automatically
* ContainerId: id attribute for the container element
* ContainerClasses: additional classes for the container element
* MarkdownPreviewInRepo: the repo to preview markdown
* MarkdownPreviewContext: preview context (the related url path when rendering) for the preview tab, eg: repo link or user home link
* MarkdownPreviewMode: content mode for the editor, eg: wiki, comment or default, can be disabled by "none"
* MarkdownEditorContext: the context data for the editor, see backend MarkdownEditorContext
* TextareaName: name attribute for the textarea
* TextareaContent: content for the textarea
* TextareaMaxLength: maxlength attribute for the textarea
@@ -14,20 +12,19 @@
* DisableAutosize: whether to disable automatic height resizing
*/}}
{{$ariaLabel := or .TextareaAriaLabel .TextareaPlaceholder}}
{{$repo := .MarkdownPreviewInRepo}}
{{$previewContext := .MarkdownPreviewContext}}
{{$previewMode := .MarkdownPreviewMode}}
{{$previewUrl := print AppSubUrl "/-/markup"}}
{{if $repo}}
{{$previewUrl = print $repo.Link "/markup"}}
{{end}}
{{$editorContext := .MarkdownEditorContext}}
{{$previewMode := or $editorContext.PreviewMode ""}}
{{$previewContext := or $editorContext.PreviewContext ""}}
{{$previewLink := or $editorContext.PreviewLink (print AppSubUrl "/-/markup")}}
{{$mentionsLink := or $editorContext.MentionsLink ""}}
{{$supportEasyMDE := or (eq $previewMode "comment") (eq $previewMode "wiki")}}
<div {{if .ContainerId}}id="{{.ContainerId}}"{{end}} class="combo-markdown-editor {{if .CustomInit}}custom-init{{end}} {{.ContainerClasses}}"
data-dropzone-parent-container="{{.DropzoneParentContainer}}"
data-content-mode="{{$previewMode}}"
data-support-easy-mde="{{$supportEasyMDE}}"
data-preview-url="{{$previewUrl}}"
data-preview-url="{{$previewLink}}"
data-preview-context="{{$previewContext}}"
{{if $mentionsLink}}data-mentions-url="{{$mentionsLink}}"{{end}}
>
{{if ne $previewMode "none"}}
<div class="ui top tabular menu">
@@ -58,7 +55,7 @@
<md-task-list class="markdown-toolbar-button" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.list.task.tooltip"}}">{{svg "octicon-tasklist"}}</md-task-list>
<button class="markdown-toolbar-button markdown-button-table-add" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.table.add.tooltip"}}">{{svg "octicon-table"}}</button>
</div>
{{if eq $previewMode "comment"}}
{{if $mentionsLink}}
<div class="markdown-toolbar-group">
<md-mention class="markdown-toolbar-button" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.mention.tooltip"}}">{{svg "octicon-mention"}}</md-mention>
<md-ref class="markdown-toolbar-button" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.ref.tooltip"}}">{{svg "octicon-cross-reference"}}</md-ref>