Files
gitea/templates/user/dashboard/feeds.tmpl
T
722e52334a fix(feed): use meaningful lines as comment excerpt (#39276)
Comment excerpts in activity feeds previously used either the first 200
display characters of a comment or, for review comments, its first
physical line. That excerpt is rendered as Markdown in the feed, so if
the excerpt began with a leading blank lines or structural markdown
syntax, the excerpt would render as empty or produce broken output. For
example, a review comment beginning with a code fence stored only the
opening fence, which rendered as an empty code block.

This commit instead renders feed excerpts as prose only, dropping code,
math, tables, images and HTML, which also fixes already stored excerpts.
New excerpts start at the first prose line, and review comments get the
same excerpt as issue comments.

This produces meaningful excerpts in more cases while preserving their
original Markdown.

---

For a comment that contains the following:

````
```
some code
```

hello
````

This previously rendered as:
 
<img width="816" height="118" alt="Screenshot 2026-09-08 at 5 06 47 PM"
src="https://github.com/user-attachments/assets/9d125363-72de-46bf-b47a-961245a79c5f"
/>

And now renders as:

<img width="807" height="89" alt="Screenshot 2026-09-08 at 5 08 30 PM"
src="https://github.com/user-attachments/assets/d2dcdc6d-d7a9-437f-8e9c-b845fe99fa5e"
/>

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bircni <bircni@icloud.com>
2026-09-25 03:08:15 +00:00

132 lines
8.1 KiB
Handlebars

<div id="activity-feed" class="flex-divided-list items-with-main" data-ref-issue-container>
{{range .Feeds}}
<div class="item">
<div class="item-leading">
{{ctx.AvatarUtils.AvatarByAction .}}
</div>
<div class="item-main tw-gap-2">
<div>
{{if gt .ActUser.ID 0}}
<a href="{{AppSubUrl}}/{{(.GetActUserName ctx) | PathEscape}}" title="{{.GetActDisplayNameTitle ctx}}">{{.GetActDisplayName ctx}}</a>
{{else}}
{{.ShortActUserName ctx}}
{{end}}
{{if .GetOpType.InActions "create_repo"}}
{{ctx.Locale.Tr "action.create_repo" (.GetRepoLink ctx) (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "rename_repo"}}
{{ctx.Locale.Tr "action.rename_repo" .GetContent (.GetRepoLink ctx) (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "commit_repo"}}
{{if .Content}}
{{ctx.Locale.Tr "action.commit_repo" (.GetRepoLink ctx) (.GetRefLink ctx) .GetBranch (.ShortRepoPath ctx)}}
{{else}}
{{ctx.Locale.Tr "action.create_branch" (.GetRepoLink ctx) (.GetRefLink ctx) .GetBranch (.ShortRepoPath ctx)}}
{{end}}
{{else if .GetOpType.InActions "create_issue"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.create_issue" (printf "%s/issues/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "create_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.create_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "transfer_repo"}}
{{ctx.Locale.Tr "action.transfer_repo" .GetContent (.GetRepoLink ctx) (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "push_tag"}}
{{ctx.Locale.Tr "action.push_tag" (.GetRepoLink ctx) (.GetRefLink ctx) .GetTag (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "comment_issue"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.comment_issue" (printf "%s/issues/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "merge_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.merge_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "close_issue"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.close_issue" (printf "%s/issues/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "reopen_issue"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.reopen_issue" (printf "%s/issues/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "close_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.close_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "reopen_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.reopen_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "delete_tag"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.delete_tag" (.GetRepoLink ctx) .GetTag (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "delete_branch"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.delete_branch" (.GetRepoLink ctx) .GetBranch (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "mirror_sync_push"}}
{{ctx.Locale.Tr "action.mirror_sync_push" (.GetRepoLink ctx) (.GetRefLink ctx) .RefName (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "mirror_sync_create"}}
{{ctx.Locale.Tr "action.mirror_sync_create" (.GetRepoLink ctx) (.GetRefLink ctx) .RefName (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "mirror_sync_delete"}}
{{ctx.Locale.Tr "action.mirror_sync_delete" (.GetRepoLink ctx) .RefName (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "approve_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.approve_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "reject_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.reject_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "comment_pull"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.comment_pull" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{else if .GetOpType.InActions "publish_release"}}
{{$linkText := .Content | ctx.RenderUtils.RenderEmoji}}
{{ctx.Locale.Tr "action.publish_release" (.GetRepoLink ctx) (printf "%s/releases/tag/%s" (.GetRepoLink ctx) .GetTag) (.ShortRepoPath ctx) $linkText}}
{{else if .GetOpType.InActions "pull_review_dismissed"}}
{{$index := index .GetIssueInfos 0}}
{{$reviewer := index .GetIssueInfos 1}}
{{ctx.Locale.Tr "action.review_dismissed" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx) $reviewer}}
{{else if .GetOpType.InActions "auto_merge_pull_request"}}
{{$index := index .GetIssueInfos 0}}
{{ctx.Locale.Tr "action.auto_merge_pull_request" (printf "%s/pulls/%s" (.GetRepoLink ctx) $index) $index (.ShortRepoPath ctx)}}
{{end}}
{{DateUtils.TimeSince .GetCreate}}
</div>
{{if .GetOpType.InActions "commit_repo" "mirror_sync_push"}}
{{$push := ActionContent2Commits .}}
{{$repoLink := (.GetRepoLink ctx)}}
{{$repo := .Repo}}
<div class="tw-flex tw-flex-col tw-gap-1">
{{range $pushCommit := $push.Commits}}
{{$commitLink := printf "%s/commit/%s" $repoLink $pushCommit.Sha1}}
<div class="flex-text-block">
{{ctx.RenderUtils.AvatarStackPushCommit $pushCommit}}
<a class="ui sha label" href="{{$commitLink}}">{{ShortSha $pushCommit.Sha1}}</a>
<span class="tw-inline-block tw-truncate">
{{ctx.RenderUtils.RenderCommitMessage $pushCommit.Message $repo}}
</span>
</div>
{{end}}
</div>
{{if and (gt $push.Len 1) $push.CompareURL}}
<a href="{{AppSubUrl}}/{{$push.CompareURL}}">{{ctx.Locale.Tr "action.compare_commits" $push.Len}} »</a>
{{end}}
{{else if .GetOpType.InActions "create_issue"}}
<span class="tw-inline-block tw-truncate issue title">{{index .GetIssueInfos 1 | ctx.RenderUtils.RenderIssueSimpleTitle}}</span>
{{else if .GetOpType.InActions "create_pull_request"}}
<span class="tw-inline-block tw-truncate issue title">{{index .GetIssueInfos 1 | ctx.RenderUtils.RenderIssueSimpleTitle}}</span>
{{else if .GetOpType.InActions "comment_issue" "approve_pull_request" "reject_pull_request" "comment_pull"}}
<a href="{{.GetCommentLink ctx}}" class="tw-inline-block tw-truncate tw-max-w-full tw-self-start issue title">{{(.GetIssueTitle ctx) | ctx.RenderUtils.RenderIssueSimpleTitle}}</a>
{{with index .GetIssueInfos 1}}
{{with ctx.RenderUtils.FeedExcerptToHtml .}}
<div class="render-content markup">{{.}}</div>
{{end}}
{{end}}
{{else if .GetOpType.InActions "merge_pull_request"}}
<div class="item-body tw-text-text">{{index .GetIssueInfos 1 | ctx.RenderUtils.RenderIssueSimpleTitle}}</div>
{{else if .GetOpType.InActions "close_issue" "reopen_issue" "close_pull_request" "reopen_pull_request"}}
<span class="tw-inline-block tw-truncate issue title">{{(.GetIssueTitle ctx) | ctx.RenderUtils.RenderIssueSimpleTitle}}</span>
{{else if .GetOpType.InActions "pull_review_dismissed"}}
<div class="item-body tw-text-text">{{ctx.Locale.Tr "action.review_dismissed_reason"}}</div>
<div class="item-body tw-text-text">{{index .GetIssueInfos 2 | ctx.RenderUtils.RenderEmoji}}</div>
{{end}}
</div>
<div class="item-trailing">
{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32 "tw-text-text-light tw-mr-1"}}
</div>
</div>
{{end}}
{{template "base/paginate" .}}
</div>