初始提交: Gitea 项目代码

This commit is contained in:
root
2026-05-30 22:47:36 +08:00
commit f288f76350
6116 changed files with 776822 additions and 0 deletions
@@ -0,0 +1,10 @@
{{if ctx.RootData.IsSigned}}
<div class="item action ui dropdown jump pointing top right select-reaction" data-action-url="{{.ActionURL}}" aria-label="{{ctx.Locale.Tr "repo.reactions"}}">
<a class="muted">{{svg "octicon-smiley"}}</a>
<div class="menu">
{{range $value := AllowedReactions}}
<a class="item emoji" data-tooltip-content="{{$value}}" aria-label="{{$value}}" data-reaction-content="{{$value}}" data-global-click="onCommentReactionButtonClick">{{ReactionToEmoji $value}}</a>
{{end}}
</div>
</div>
{{end}}
@@ -0,0 +1,42 @@
<div class="dropzone-attachments">
{{if .Attachments}}
<div class="divider"></div>
{{end}}
{{$hasThumbnails := false}}
{{- range .Attachments -}}
<div class="tw-flex">
<div class="tw-flex-1 tw-p-2">
<a target="_blank" href="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
{{if FilenameIsImage .Name}}
{{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}}
{{$hasThumbnails = true}}
{{end}}
{{svg "octicon-file"}}
{{else}}
{{svg "octicon-desktop-download"}}
{{end}}
<span><strong>{{.Name}}</strong></span>
</a>
</div>
<div class="flex-text-block tw-p-2">
<span class="ui tw-text-text-light">{{.Size | FileSize}}</span>
</div>
</div>
{{end -}}
{{if $hasThumbnails}}
<div class="divider"></div>
<div class="ui small thumbnails">
{{- range .Attachments -}}
{{if FilenameIsImage .Name}}
{{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}}
<a target="_blank" href="{{.DownloadURL}}">
<img loading="lazy" alt="{{.Name}}" src="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
</a>
{{end}}
{{end}}
{{end -}}
</div>
{{end}}
</div>
@@ -0,0 +1,699 @@
{{template "base/alert"}}
{{range $comment := .Issue.Comments}}
{{if call $.ShouldShowCommentType .Type}}
{{$createdStr:= DateUtils.TimeSince .CreatedUnix}}
<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF,
5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 8 = MILESTONE_CHANGE,
9 = ASSIGNEES_CHANGE, 10 = TITLE_CHANGE, 11 = DELETE_BRANCH, 12 = START_TRACKING,
13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL, 16 = ADDED_DEADLINE, 17 = MODIFIED_DEADLINE,
18 = REMOVED_DEADLINE, 19 = ADD_DEPENDENCY, 20 = REMOVE_DEPENDENCY, 21 = CODE,
22 = REVIEW, 23 = ISSUE_LOCKED, 24 = ISSUE_UNLOCKED, 25 = TARGET_BRANCH_CHANGED,
26 = DELETE_TIME_MANUAL, 27 = REVIEW_REQUEST, 28 = MERGE_PULL_REQUEST,
29 = PULL_PUSH_EVENT, 30 = PROJECT_CHANGED, 31 = PROJECT_BOARD_CHANGED
32 = DISMISSED_REVIEW, 33 = COMMENT_TYPE_CHANGE_ISSUE_REF, 34 = PR_SCHEDULE_TO_AUTO_MERGE,
35 = CANCEL_SCHEDULED_AUTO_MERGE_PR, 36 = PIN_ISSUE, 37 = UNPIN_ISSUE,
38 = COMMENT_TYPE_CHANGE_TIME_ESTIMATE -->
{{if eq .Type 0}}
<div class="timeline-item comment" id="{{.HashTag}}">
{{if .OriginalAuthor}}
<span class="timeline-avatar">
{{ctx.AvatarUtils.Avatar nil 40}}
</span>
{{else}}
<a class="timeline-avatar"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
{{ctx.AvatarUtils.Avatar .Poster 40}}
</a>
{{end}}
<div class="content comment-container">
<div class="comment-header avatar-content-left-arrow" role="heading" aria-level="3">
<div class="comment-header-left">
{{if .OriginalAuthor}}
<span class="tw-text-text tw-font-semibold tw-mr-1">
{{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}}
{{.OriginalAuthor}}
</span>
<span class="comment-text-line">
{{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdStr}} {{if $.Repository.OriginalURL}}
</span>
<span class="text migrate">
({{ctx.Locale.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname}}){{end}}
</span>
{{else}}
{{if gt .Poster.ID 0}}
<a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}">
{{ctx.AvatarUtils.Avatar .Poster 24}}
</a>
{{end}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdStr}}
</span>
{{end}}
</div>
<div class="comment-header-right">
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
{{end}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
</div>
</div>
<div class="ui attached segment comment-body" role="article">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}}
{{.RenderedContent}}
{{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}}
</div>
<div id="{{.HashTag}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
<div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
{{if .Attachments}}
{{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
{{end}}
</div>
{{$reactions := .Reactions.GroupByType}}
{{if $reactions}}
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
{{end}}
</div>
</div>
{{else if eq .Type 1}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge tw-bg-green tw-text-white">{{svg "octicon-dot-fill"}}</span>
{{if not .OriginalAuthor}}
{{template "shared/user/avatarlink" dict "user" .Poster}}
{{end}}
<span class="comment-text-line">
{{template "repo/issue/view_content/comments_authorlink" dict "comment" .}}
{{if .Issue.IsPull}}
{{ctx.Locale.Tr "repo.pulls.reopened_at" .EventTag $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.reopened_at" .EventTag $createdStr}}
{{end}}
</span>
</div>
{{else if eq .Type 2}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge tw-bg-red tw-text-white">{{svg "octicon-issue-closed"}}</span>
{{if not .OriginalAuthor}}
{{template "shared/user/avatarlink" dict "user" .Poster}}
{{end}}
<span class="comment-text-line">
{{template "repo/issue/view_content/comments_authorlink" dict "comment" .}}
{{if .Issue.IsPull}}
{{ctx.Locale.Tr "repo.pulls.closed_at" .EventTag $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.closed_at" .EventTag $createdStr}}
{{end}}
</span>
</div>
{{else if eq .Type 28}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge tw-bg-purple tw-text-white">{{svg "octicon-git-merge"}}</span>
{{if not .OriginalAuthor}}
{{template "shared/user/avatarlink" dict "user" .Poster}}
{{end}}
<span class="comment-text-line">
{{template "repo/issue/view_content/comments_authorlink" dict "comment" .}}
{{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}}
{{if eq $.Issue.PullRequest.Status 3}}
{{ctx.Locale.Tr "repo.issues.comment_manually_pull_merged_at" (HTMLFormat `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` $link (ShortSha $.Issue.PullRequest.MergedCommitID)) (HTMLFormat "<b>%[1]s</b>" $.BaseTarget) $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.comment_pull_merged_at" (HTMLFormat `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` $link (ShortSha $.Issue.PullRequest.MergedCommitID)) (HTMLFormat "<b>%[1]s</b>" $.BaseTarget) $createdStr}}
{{end}}
</span>
</div>
{{else if eq .Type 3 5 6}}
{{$refFrom:= ""}}
{{if ne .RefRepoID .Issue.RepoID}}
{{$refFrom = ctx.Locale.Tr "repo.issues.ref_from" .RefRepo.FullName}}
{{end}}
{{$refTr := "repo.issues.ref_issue_from"}}
{{if .Issue.IsPull}}
{{$refTr = "repo.issues.ref_pull_from"}}
{{else if eq .RefAction 1}}
{{$refTr = "repo.issues.ref_closing_from"}}
{{else if eq .RefAction 2}}
{{$refTr = "repo.issues.ref_reopening_from"}}
{{end}}
{{$createdStr:= DateUtils.TimeSince .CreatedUnix}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-bookmark"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{if eq .RefAction 3}}<del>{{end}}
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr $refTr .EventTag $createdStr (.RefCommentLink ctx) $refFrom}}
{{if eq .RefAction 3}}</del>{{end}}
</span>
<div class="detail flex-text-block">
<span class="comment-text-line"><a href="{{.RefIssueLink ctx}}"><b>{{.RefIssueTitle ctx}}</b> {{.RefIssueIdent ctx}}</a></span>
</div>
</div>
{{else if eq .Type 4}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-bookmark"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.commit_ref_at" .EventTag $createdStr}}
</span>
<div class="detail flex-text-block">
{{svg "octicon-git-commit"}}
{{/* the content is a link like <a href="{RepoLink}/commit/{CommitID}">message title</a> (from CreateRefComment) */}}
<span class="comment-text-line">{{.GetSanitizedContentHTML}}</span>
</div>
</div>
{{else if eq .Type 7}}
{{if or .AddedLabels .RemovedLabels}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-tag"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{if and .AddedLabels (not .RemovedLabels)}}
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (ctx.RenderUtils.RenderLabels .AddedLabels $.RepoLink .Issue) $createdStr}}
{{else if and (not .AddedLabels) .RemovedLabels}}
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (ctx.RenderUtils.RenderLabels .RemovedLabels $.RepoLink .Issue) $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (ctx.RenderUtils.RenderLabels .AddedLabels $.RepoLink .Issue) (ctx.RenderUtils.RenderLabels .RemovedLabels $.RepoLink .Issue) $createdStr}}
{{end}}
</span>
</div>
{{end}}
{{else if eq .Type 8}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-milestone"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{if gt .OldMilestoneID 0}}{{if gt .MilestoneID 0}}{{ctx.Locale.Tr "repo.issues.change_milestone_at" .OldMilestone.Name .Milestone.Name $createdStr}}{{else}}{{ctx.Locale.Tr "repo.issues.remove_milestone_at" .OldMilestone.Name $createdStr}}{{end}}{{else if gt .MilestoneID 0}}{{ctx.Locale.Tr "repo.issues.add_milestone_at" .Milestone.Name $createdStr}}{{end}}
</span>
</div>
{{else if and (eq .Type 9) (gt .AssigneeID 0)}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-person"}}</span>
{{if .RemovedAssignee}}
{{template "shared/user/avatarlink" dict "user" .Assignee}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Assignee}}
{{if eq .Poster.ID .Assignee.ID}}
{{ctx.Locale.Tr "repo.issues.remove_self_assignment" $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.remove_assignee_at" .Poster.GetDisplayName $createdStr}}
{{end}}
</span>
{{else}}
{{template "shared/user/avatarlink" dict "user" .Assignee}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Assignee}}
{{if eq .Poster.ID .AssigneeID}}
{{ctx.Locale.Tr "repo.issues.self_assign_at" $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.add_assignee_at" .Poster.GetDisplayName $createdStr}}
{{end}}
</span>
{{end}}
</div>
{{else if eq .Type 10}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{ctx.RenderUtils.RenderTimelineEventBadge $comment}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.RenderUtils.RenderTimelineEventComment $comment $createdStr}}
</span>
</div>
{{else if eq .Type 11}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-git-branch"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$oldRef := HTMLFormat `<span class="tw-line-through">%s</span>` .OldRef}}
{{ctx.Locale.Tr "repo.issues.delete_branch_at" $oldRef $createdStr}}
</span>
</div>
{{else if eq .Type 12}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.start_tracking_history" $createdStr}}
</span>
</div>
{{else if eq .Type 13}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$timeStr := .RenderedContent}} {{/* compatibility with time comments made before v1.21 */}}
{{if not $timeStr}}{{$timeStr = .Content|Sec2Hour}}{{end}}
{{ctx.Locale.Tr "repo.issues.stop_tracking_history" $timeStr $createdStr}}
</span>
{{template "repo/issue/view_content/comments_delete_time" dict "comment" .}}
</div>
{{else if eq .Type 14}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$timeStr := .RenderedContent}} {{/* compatibility with time comments made before v1.21 */}}
{{if not $timeStr}}{{$timeStr = .Content|Sec2Hour}}{{end}}
{{ctx.Locale.Tr "repo.issues.add_time_history" $timeStr $createdStr}}
</span>
{{template "repo/issue/view_content/comments_delete_time" dict "comment" .}}
</div>
{{else if eq .Type 15}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.cancel_tracking_history" $createdStr}}
</span>
</div>
{{else if eq .Type 16}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$dueDate := DateUtils.AbsoluteLong (.Content|DateUtils.ParseLegacy)}}
{{ctx.Locale.Tr "repo.issues.due_date_added" $dueDate $createdStr}}
</span>
</div>
{{else if eq .Type 17}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$parsedDeadline := StringUtils.Split .Content "|"}}
{{if eq (len $parsedDeadline) 2}}
{{$to := DateUtils.AbsoluteLong ((index $parsedDeadline 0)|DateUtils.ParseLegacy)}}
{{$from := DateUtils.AbsoluteLong ((index $parsedDeadline 1)|DateUtils.ParseLegacy)}}
{{ctx.Locale.Tr "repo.issues.due_date_modified" $to $from $createdStr}}
{{end}}
</span>
</div>
{{else if eq .Type 18}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$dueDate := DateUtils.AbsoluteLong (.Content|DateUtils.ParseLegacy)}}
{{ctx.Locale.Tr "repo.issues.due_date_remove" $dueDate $createdStr}}
</span>
</div>
{{else if eq .Type 19}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-package-dependents"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.dependency.added_dependency" $createdStr}}
</span>
{{if .DependentIssue}}
<div class="detail flex-text-block">
{{svg "octicon-plus"}}
<span class="comment-text-line">
<a href="{{.DependentIssue.Link}}">
{{if eq .DependentIssue.RepoID .Issue.RepoID}}
#{{.DependentIssue.Index}} {{.DependentIssue.Title}}
{{else}}
{{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{.DependentIssue.Title}}
{{end}}
</a>
</span>
</div>
{{end}}
</div>
{{else if eq .Type 20}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-package-dependents"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.dependency.removed_dependency" $createdStr}}
</span>
{{if .DependentIssue}}
<div class="detail flex-text-block">
{{svg "octicon-trash"}}
<span class="comment-text-line">
<a href="{{.DependentIssue.Link}}">
{{if eq .DependentIssue.RepoID .Issue.RepoID}}
#{{.DependentIssue.Index}} {{.DependentIssue.Title}}
{{else}}
{{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{.DependentIssue.Title}}
{{end}}
</a>
</span>
</div>
{{end}}
</div>
{{else if eq .Type 22}}
<div class="timeline-item-group" id="{{.HashTag}}">
<div class="timeline-item event">
{{$reviewType := 2}}{{/* default to "comment" type if the review record is missing */}}
{{if .Review}}{{$reviewType = .Review.Type}}{{end}}
{{if not .OriginalAuthor}}
{{/* Some timeline avatars need a offset to correctly align with their speech bubble.
The condition depends on whether the comment has contents/attachments,
review's comment is also controlled/rendered by issue comment's Content field */}}
<a class="timeline-avatar{{if or .Content .Attachments}} timeline-avatar-offset{{end}}"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
{{ctx.AvatarUtils.Avatar .Poster 40}}
</a>
{{end}}
<span class="badge tw-text-white {{if eq $reviewType 1}}{{Iif .Review.Official "tw-bg-green" "tw-bg-grey"}}{{else if eq $reviewType 3}}tw-bg-red{{end}}">
{{- if .Review -}}
{{- svg (printf "octicon-%s" .Review.Type.Icon) -}}
{{- else -}}
{{- svg "octicon-comment" -}}
{{- end -}}
</span>
<span class="comment-text-line">
{{template "repo/issue/view_content/comments_authorlink" dict "comment" .}}
{{if eq $reviewType 1}}
{{ctx.Locale.Tr "repo.issues.review.approve" $createdStr}}
{{else if eq $reviewType 3}}
{{ctx.Locale.Tr "repo.issues.review.reject" $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.review.comment" $createdStr}}
{{end}}
{{if and .Review .Review.Dismissed}}
<div class="ui small label">{{ctx.Locale.Tr "repo.issues.review.dismissed_label"}}</div>
{{end}}
</span>
</div>
{{if or .Content .Attachments}}
<div class="timeline-item comment">
<div class="content comment-container">
<div class="comment-header avatar-content-left-arrow">
<div class="comment-header-left">
{{if gt .Poster.ID 0}}
<a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}">
{{ctx.AvatarUtils.Avatar .Poster 24}}
</a>
{{end}}
<span class="comment-text-line">
{{if .OriginalAuthor}}
<span class="tw-text-text tw-font-semibold">
{{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}}
{{.OriginalAuthor}}
</span>
<span class="comment-text-line"> {{if $.Repository.OriginalURL}}</span>
<span class="text migrate">({{ctx.Locale.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname}}){{end}}</span>
{{else}}
{{template "shared/user/authorlink" .Poster}}
{{end}}
{{ctx.Locale.Tr "repo.issues.review.left_comment"}}
</span>
</div>
<div class="comment-header-right">
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{end}}
</div>
</div>
<div class="ui attached segment comment-body">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}}
{{.RenderedContent}}
{{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}}
</div>
<div id="{{.HashTag}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
<div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
{{if .Attachments}}
{{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
{{end}}
</div>
{{$reactions := .Reactions.GroupByType}}
{{if $reactions}}
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
{{end}}
</div>
</div>
{{end}}
{{if and .Review .Review.CodeComments}}
<div class="timeline-item event code-comments-list">
{{range $filename, $lines := .Review.CodeComments}}
{{range $line, $comms := $lines}}
{{template "repo/issue/view_content/conversation" dict "." $ "comments" $comms}}
{{end}}
{{end}}
</div>
{{end}}
</div>
{{else if eq .Type 23}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-lock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
{{if .Content}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.lock_with_reason" .Content $createdStr}}
</span>
{{else}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.lock_no_reason" $createdStr}}
</span>
{{end}}
</div>
{{else if eq .Type 24}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-key"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.unlock_comment" $createdStr}}
</span>
</div>
{{else if eq .Type 25}}
<div class="timeline-item event">
<span class="badge">{{svg "octicon-git-branch"}}</span>
{{if not .OriginalAuthor}}
{{template "shared/user/avatarlink" dict "user" .Poster}}
{{end}}
<span class="comment-text-line">
{{template "repo/issue/view_content/comments_authorlink" dict "comment" .}}
{{ctx.Locale.Tr "repo.pulls.change_target_branch_at" .OldRef .NewRef $createdStr}}
</span>
</div>
{{else if eq .Type 26}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.del_time_history" $createdStr}}
</span>
<div class="detail flex-text-block">
{{svg "octicon-clock"}}
{{if .RenderedContent}}
{{/* compatibility with time comments made before v1.21 */}}
<span class="comment-text-line">{{.RenderedContent}}</span>
{{else}}
<span class="comment-text-line">- {{.Content|Sec2Hour}}</span>
{{end}}
</div>
</div>
{{else if eq .Type 27}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-eye"}}</span>
{{$specialDoerHtml := .MetaSpecialDoerTr ctx.Locale}}
{{$timelineRequestedReviewHtml := .TimelineRequestedReviewTr ctx.Locale $createdStr}}
{{if $specialDoerHtml}}
<span class="comment-text-line">
{{$specialDoerHtml}}
{{$timelineRequestedReviewHtml}}
</span>
{{else}}
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$timelineRequestedReviewHtml}}
</span>
{{end}}
</div>
{{else if and (eq .Type 29) (or (gt .CommitsNum 0) .IsForcePush)}}
<!-- If PR is closed, the comments whose type is CommentTypePullRequestPush(29) after latestCloseCommentID won't be rendered. //-->
{{if and .Issue.IsClosed (gt .ID $.LatestCloseCommentID)}}
{{continue}}
{{end}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-repo-push"}}</span>
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{if .IsForcePush}}
{{ctx.Locale.Tr "repo.issues.force_push_codes" $.Issue.PullRequest.HeadBranch (ShortSha .OldCommit) ($.Issue.Repo.CommitLink .OldCommit) (ShortSha .NewCommit) ($.Issue.Repo.CommitLink .NewCommit) $createdStr}}
{{else}}
{{ctx.Locale.TrN (len .Commits) "repo.issues.push_commit_1" "repo.issues.push_commits_n" (len .Commits) $createdStr}}
{{end}}
</span>
{{if and .IsForcePush $.Issue.PullRequest.BaseRepo.Name}}
<a class="ui label comment-text-label tw-ml-auto" href="{{$.Issue.PullRequest.BaseRepo.Link}}/compare/{{PathEscape .OldCommit}}..{{PathEscape .NewCommit}}" rel="nofollow">{{ctx.Locale.Tr "repo.issues.force_push_compare"}}</a>
{{end}}
</div>
{{if not .IsForcePush}}
{{template "repo/commits_list_small" dict "comment" . "root" $}}
{{end}}
{{else if eq .Type 30}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-project"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$oldProjectDisplayHtml := "Unknown Project"}}
{{if .OldProject}}
{{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}}
{{if not .OldProject.IsGhost}}
{{$tooltip = ctx.Locale.Tr (printf "projects.type-%d.display_name" .OldProject.Type)}}
{{end}}
{{$oldProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` $tooltip .OldProject.Title}}
{{end}}
{{$newProjectDisplayHtml := "Unknown Project"}}
{{if .Project}}
{{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}}
{{if not .Project.IsGhost}}
{{$tooltip = ctx.Locale.Tr (printf "projects.type-%d.display_name" .Project.Type)}}
{{end}}
{{$newProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` $tooltip .Project.Title}}
{{end}}
{{if and (gt .OldProjectID 0) (gt .ProjectID 0)}}
{{ctx.Locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr}}
{{else if gt .OldProjectID 0}}
{{ctx.Locale.Tr "repo.issues.remove_project_at" $oldProjectDisplayHtml $createdStr}}
{{else if gt .ProjectID 0}}
{{ctx.Locale.Tr "repo.issues.add_project_at" $newProjectDisplayHtml $createdStr}}
{{end}}
</span>
</div>
{{else if eq .Type 31}}
{{if not $.UnitProjectsGlobalDisabled}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-project"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$newProjectDisplay := .CommentMetaData.ProjectTitle}}
{{if .Project}}
{{$trKey := printf "projects.type-%d.display_name" .Project.Type}}
{{$newProjectDisplay = HTMLFormat `%s <a href="%s"><span data-tooltip-content="%s">%s</span></a>` (svg .Project.IconName) (.Project.Link ctx) (ctx.Locale.Tr $trKey) .Project.Title}}
{{end}}
{{ctx.Locale.Tr "repo.issues.move_to_column_of_project" .CommentMetaData.ProjectColumnTitle $newProjectDisplay $createdStr}}
</span>
</div>
{{end}}
{{else if eq .Type 32}}
<div class="timeline-item-group">
<div class="timeline-item event" id="{{.HashTag}}">
<a class="timeline-avatar"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>
{{ctx.AvatarUtils.Avatar .Poster 40}}
</a>
<span class="badge grey">{{svg "octicon-x" 16}}</span>
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$reviewerName := ""}}
{{if .Review}}
{{if eq .Review.OriginalAuthor ""}}
{{$reviewerName = .Review.Reviewer.Name}}
{{else}}
{{$reviewerName = .Review.OriginalAuthor}}
{{end}}
{{end}}
{{ctx.Locale.Tr "repo.issues.review.dismissed" $reviewerName $createdStr}}
</span>
</div>
{{if .Content}}
<div class="timeline-item comment">
<div class="content comment-container">
<div class="comment-header avatar-content-left-arrow arrow-top">
{{if gt .Poster.ID 0}}
<a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}">
{{ctx.AvatarUtils.Avatar .Poster 24}}
</a>
{{end}}
<span class="comment-text-line">
{{ctx.Locale.Tr "action.review_dismissed_reason"}}
</span>
</div>
<div class="ui attached segment comment-body">
<div class="render-content markup">
{{if .RenderedContent}}
{{.RenderedContent}}
{{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}}
</div>
</div>
</div>
</div>
{{end}}
</div>
{{else if eq .Type 33}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-git-branch"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{if and .OldRef .NewRef}}
{{ctx.Locale.Tr "repo.issues.change_ref_at" .OldRef .NewRef $createdStr}}
{{else if .OldRef}}
{{ctx.Locale.Tr "repo.issues.remove_ref_at" .OldRef $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.add_ref_at" .NewRef $createdStr}}
{{end}}
</span>
</div>
{{else if or (eq .Type 34) (eq .Type 35)}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-git-merge" 16}}</span>
<span class="comment-text-line">
{{template "repo/issue/view_content/comments_authorlink" dict "comment" .}}
{{if eq .Type 34}}{{ctx.Locale.Tr "repo.pulls.auto_merge_newly_scheduled_comment" $createdStr}}
{{else}}{{ctx.Locale.Tr "repo.pulls.auto_merge_canceled_schedule_comment" $createdStr}}{{end}}
</span>
</div>
{{else if or (eq .Type 36) (eq .Type 37)}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-pin" 16}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{if eq .Type 36}}{{ctx.Locale.Tr "repo.issues.pin_comment" $createdStr}}
{{else}}{{ctx.Locale.Tr "repo.issues.unpin_comment" $createdStr}}{{end}}
</span>
</div>
{{else if eq .Type 38}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-clock"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{$timeStr := .Content|TimeEstimateString}}
{{if $timeStr}}
{{ctx.Locale.Tr "repo.issues.change_time_estimate_at" $timeStr $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.remove_time_estimate_at" $createdStr}}
{{end}}
</span>
</div>
{{end}}
{{end}}
{{end}}
@@ -0,0 +1,11 @@
{{if .comment.OriginalAuthor}}
<span class="tw-text-text">
{{svg (MigrationIcon ctx.RootData.Repository.GetOriginalURLHostname)}}
{{.comment.OriginalAuthor}}
</span>
{{if ctx.RootData.Repository.OriginalURL}}
<span class="migrate">({{ctx.Locale.Tr "repo.migrated_from" ctx.RootData.Repository.OriginalURL ctx.RootData.Repository.GetOriginalURLHostname}})</span>
{{end}}
{{else}}
{{template "shared/user/authorlink" .comment.Poster}}
{{end}}
@@ -0,0 +1,14 @@
{{if and .comment.Time (ctx.RootData.Repository.IsTimetrackerEnabled ctx)}} {{/* compatibility with time comments made before v1.14 */}}
{{if (not .comment.Time.Deleted)}}
{{if (or ctx.RootData.IsAdmin (and ctx.RootData.IsSigned (eq ctx.RootData.SignedUserID .comment.PosterID)))}}
<span class="tw-ml-auto">
<button class="ui icon button compact mini link-action" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.del_time"}}"
data-url="{{ctx.RootData.RepoLink}}/issues/{{ctx.RootData.Issue.Index}}/times/{{.comment.TimeID}}/delete?id={{.comment.Time.ID}}"
data-modal-confirm="{{ctx.Locale.Tr "repo.issues.del_time"}}"
>
{{svg "octicon-trash"}}
</button>
</span>
{{end}}
{{end}}
{{end}}
@@ -0,0 +1,45 @@
<div class="item action ui dropdown jump pointing top right context-dropdown">
<a class="context-menu muted">
{{svg "octicon-kebab-horizontal"}}
</a>
<div class="menu">
{{$referenceLink := ""}}
{{if .issue}}
{{$referenceLink = printf "%s#%s" ctx.RootData.Issue.Link .item.HashTag}}
{{else}}
{{$referenceLink = printf "%s/files#%s" ctx.RootData.Issue.Link .item.HashTag}}
{{end}}
<div class="item context js-aria-clickable" data-clipboard-text="{{ctx.AppFullLink}}{{$referenceLink}}">{{ctx.Locale.Tr "repo.issues.context.copy_link"}}</div>
<div class="item context js-aria-clickable" data-clipboard-target="#{{.item.HashTag}}-raw">{{ctx.Locale.Tr "repo.issues.context.copy_source"}}</div>
{{if ctx.RootData.IsSigned}}
{{$needDivider := false}}
{{if not ctx.RootData.Repository.IsArchived}}
{{$needDivider = true}}
<div class="item context js-aria-clickable quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.HashTag}}-raw">{{ctx.Locale.Tr "repo.issues.context.quote_reply"}}</div>
{{if not ctx.Consts.RepoUnitTypeIssues.UnitGlobalDisabled}}
<div class="item context js-aria-clickable reference-issue" data-target="{{.item.HashTag}}-raw" data-modal="#reference-issue-modal" data-poster="{{.item.Poster.GetDisplayName}}" data-poster-username="{{.item.Poster.Name}}" data-reference="{{$referenceLink}}">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</div>
{{end}}
{{if or ctx.RootData.Permission.IsAdmin .IsCommentPoster ctx.RootData.HasIssuesOrPullsWritePermission}}
<div class="divider"></div>
<div class="item context js-aria-clickable edit-content">{{ctx.Locale.Tr "repo.issues.context.edit"}}</div>
{{if .delete}}
<div class="item context js-aria-clickable delete-comment" data-comment-id={{.item.HashTag}} data-url="{{ctx.RootData.RepoLink}}/comments/{{.item.ID}}/delete" data-locale="{{ctx.Locale.Tr "repo.issues.delete_comment_confirm"}}">{{ctx.Locale.Tr "repo.issues.context.delete"}}</div>
{{end}}
{{end}}
{{end}}
{{$canUserBlock := call ctx.RootData.CanBlockUser ctx.RootData.SignedUser .item.Poster}}
{{$canOrgBlock := and ctx.RootData.Repository.Owner.IsOrganization (call ctx.RootData.CanBlockUser ctx.RootData.Repository.Owner .item.Poster)}}
{{if or $canOrgBlock $canUserBlock}}
{{if $needDivider}}
<div class="divider"></div>
{{end}}
{{if $canUserBlock}}
<div class="item context js-aria-clickable show-modal" data-modal="#block-user-modal" data-modal-modal-blockee="{{.item.Poster.Name}}" data-modal-modal-blockee-name="{{.item.Poster.GetDisplayName}}" data-modal-modal-form.action="{{AppSubUrl}}/user/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.user"}}</div>
{{end}}
{{if $canOrgBlock}}
<div class="item context js-aria-clickable show-modal" data-modal="#block-user-modal" data-modal-modal-blockee="{{.item.Poster.Name}}" data-modal-modal-blockee-name="{{.item.Poster.GetDisplayName}}" data-modal-modal-form.action="{{ctx.RootData.Repository.Owner.OrganisationLink}}/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.org"}}</div>
{{end}}
{{end}}
{{end}}
</div>
</div>
@@ -0,0 +1,148 @@
{{/* FIXME: DIFF-CONVERSATION-DATA: in the future this template should be refactor to avoid called by {{... "." $}}
At the moment, two kinds of request handler call this template:
* ExcerptBlob -> blob_excerpt.tmpl -> this
* Other compare and diff pages -> ... -> {section_unified.tmpl|section_split.tmpl} -> this)
The variables in "ctx.Data" are different in each case, making this template fragile, hard to read and maintain. */}}
{{if len .comments}}
{{$comment := index .comments 0}}
{{$invalid := $comment.Invalidated}}
{{$resolved := $comment.IsResolved}}
{{$resolveDoer := $comment.ResolveDoer}}
{{$hasReview := and $comment.Review}}
{{$isReviewPending := and $hasReview (eq $comment.Review.Type 0)}}
<div class="ui segments conversation-holder">
<div class="ui segment collapsible-comment-box tw-py-2 flex-left-right">
<div class="tw-flex tw-items-center">
<a href="{{$comment.CodeCommentLink ctx}}" class="file-comment tw-ml-2 tw-break-anywhere">{{$comment.TreePath}}</a>
{{if $invalid}}
<span class="ui label basic small tw-ml-2" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}">
{{ctx.Locale.Tr "repo.issues.review.outdated"}}
</span>
{{end}}
</div>
<div class="tw-flex tw-items-center">
{{if or $invalid $resolved}}
<button id="show-outdated-{{$comment.ID}}" data-comment="{{$comment.ID}}" class="{{if not $resolved}}tw-hidden{{end}} btn tiny show-outdated">
{{svg "octicon-unfold" 16 "tw-mr-2"}}
{{if $resolved}}
{{ctx.Locale.Tr "repo.issues.review.show_resolved"}}
{{else}}
{{ctx.Locale.Tr "repo.issues.review.show_outdated"}}
{{end}}
</button>
<button id="hide-outdated-{{$comment.ID}}" data-comment="{{$comment.ID}}" class="{{if $resolved}}tw-hidden {{end}} btn tiny hide-outdated">
{{svg "octicon-fold" 16 "tw-mr-2"}}
{{if $resolved}}
{{ctx.Locale.Tr "repo.issues.review.hide_resolved"}}
{{else}}
{{ctx.Locale.Tr "repo.issues.review.hide_outdated"}}
{{end}}
</button>
{{end}}
</div>
</div>
{{$diff := (CommentMustAsDiff ctx $comment)}}
{{if $diff}}
{{$file := (index $diff.Files 0)}}
<div id="code-preview-{{$comment.ID}}" class="ui table segment{{if $resolved}} tw-hidden{{end}}">
<div class="diff-file-box file-content {{TabSizeClass $.Editorconfig $file.Name}}">
<div class="file-body file-code code-view code-diff code-diff-unified unicode-escaped">
<table>
<tbody>
{{template "repo/diff/section_unified" dict "file" $file "root" $}}
</tbody>
</table>
</div>
</div>
</div>
{{end}}
<div id="code-comments-{{$comment.ID}}" class="comment-code-cloud ui segment{{if $resolved}} tw-hidden{{end}}">
<div class="ui comments tw-mb-0">
{{range .comments}}
{{$createdSubStr:= DateUtils.TimeSince .CreatedUnix}}
<div class="comment code-comment" id="{{.HashTag}}">
<div class="content comment-container">
<div class="comment-header">
<div class="comment-header-left">
{{if not .OriginalAuthor}}
<a class="avatar">
{{ctx.AvatarUtils.Avatar .Poster 20}}
</a>
{{end}}
<span class="tw-text-text-light muted-links">
{{if .OriginalAuthor}}
<span class="tw-text-text">
{{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}}
{{.OriginalAuthor}}
</span>
{{if $.Repository.OriginalURL}}
<span class="migrate">({{ctx.Locale.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname}})</span>
{{end}}
{{else}}
{{template "shared/user/authorlink" .Poster}}
{{end}}
{{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdSubStr}}
</span>
</div>
<div class="comment-header-right">
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{end}}
</div>
</div>
<div class="text comment-content">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}}
{{.RenderedContent}}
{{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}}
</div>
<div id="{{.HashTag}}-raw" class="raw-content tw-hidden">{{.Content}}</div>
<div class="edit-content-zone tw-hidden" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-content-version="{{.ContentVersion}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
{{if .Attachments}}
{{template "repo/issue/view_content/attachments" dict "Attachments" .Attachments "RenderedContent" .RenderedContent}}
{{end}}
</div>
{{$reactions := .Reactions.GroupByType}}
{{if $reactions}}
{{template "repo/issue/view_content/reactions" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
{{end}}
</div>
</div>
{{end}}
</div>
<div class="flex-text-block tw-flex-wrap tw-my-2">
<div class="tw-flex-1">
{{if $resolved}}
<div class="ui grey text">
{{svg "octicon-check" 16 "tw-mr-1"}}
<b>{{$resolveDoer.Name}}</b> {{ctx.Locale.Tr "repo.issues.review.resolved_by"}}
</div>
{{end}}
</div>
<div class="flex-text-block">
{{if and $.CanMarkConversation $hasReview (not $isReviewPending)}}
<button class="ui tiny basic button resolve-conversation" data-origin="timeline" data-action="{{if not $resolved}}Resolve{{else}}UnResolve{{end}}" data-comment-id="{{$comment.ID}}" data-update-url="{{$.RepoLink}}/issues/resolve_conversation">
{{if $resolved}}
{{ctx.Locale.Tr "repo.issues.review.un_resolve_conversation"}}
{{else}}
{{ctx.Locale.Tr "repo.issues.review.resolve_conversation"}}
{{end}}
</button>
{{end}}
{{if and $.SignedUserID (not $.Repository.IsArchived)}}
<button class="comment-form-reply ui primary icon tiny button">
{{svg "octicon-reply" 12}}{{ctx.Locale.Tr "repo.diff.comment.reply"}}
</button>
{{end}}
</div>
</div>
{{template "repo/diff/comment_form_datahandler" dict "hidden" true "reply" $comment.ReviewID "root" $ "comment" $comment}}
</div>
</div>
{{else}}
{{template "repo/diff/conversation_outdated"}}
{{end}}
@@ -0,0 +1,82 @@
{{$data := $.PullMergeBoxData}}
{{if $data.ShowMergeBox}}
<div class="timeline-item comment pull-merge-box"
data-global-init="initRepoPullMergeBox"
{{if $data.ReloadingInterval}}
data-pull-merge-box-reloading-interval="{{$data.ReloadingInterval}}"
data-pull-link="{{$.Issue.Link}}"
{{end}}
>
<div class="timeline-avatar {{$data.TimelineIconClass}}">{{svg "octicon-git-merge" 40}}</div>
<div class="content">
<div class="ui segment fitted avatar-content-left-arrow">
<div class="merge-section flex-divided-list items-px-default">
{{if $data.ShowStatusCheck}}
{{template "repo/issue/view_content/pull_merge_status_checks" (dict "StatusCheckData" $data.StatusCheckData)}}
{{end}}
{{if $data.ClosedInfoTitle}}
<div class="item flex-left-right">
<div>
<h3 class="tw-mb-2">{{$data.ClosedInfoTitle}}</h3>
<div>{{$data.ClosedInfoBody}}</div>
</div>
{{if $data.IsPullBranchDeletable}}
<div>
<button class="ui button link-action delete-branch-after-merge" data-url="{{.DeleteBranchLink}}">{{ctx.Locale.Tr "repo.branch.delete_html"}}</button>
</div>
{{end}}
</div>
{{end}}
{{range $infoSection := $data.InfoSections}}
{{if $infoSection.InfoItems}}
<div class="item">
{{range $infoItem := $infoSection.InfoItems}}
<div class="flex-text-block {{$infoItem.ItemClass}}">{{$infoItem.SvgIconHTML}} {{$infoItem.InfoHTML}}</div>
{{if $infoItem.ListItems}}
<ul class="tw-pl-[36px]">{{/* align with the info icon and text */}}
{{range $listItem := $infoItem.ListItems}}
<li>{{$listItem}}</li>
{{end}}
</ul>
{{end}}
{{end}}
</div>
{{end}}
{{end}}
{{if $data.ShowUpdatePullInfo}}
<div class="item">
{{template "repo/issue/view_content/update_branch_by_merge" (dict "MergeBoxData" $data "IssueLink" $.Issue.Link)}}
</div>
{{end}}
{{if $.IsPullWorkInProgress}}
<div class="item flex-left-right">
<div class="flex-text-block">
{{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.cannot_merge_work_in_progress"}}
</div>
{{if or .HasIssuesOrPullsWritePermission .IsIssuePoster}}
<button class="ui compact button" data-global-init="initPullRequestWipToggle" data-title="{{.Issue.Title}}" data-wip-prefix="{{.WorkInProgressPrefix}}" data-update-url="{{.Issue.Link}}/title">
{{ctx.Locale.Tr "repo.pulls.remove_prefix" .WorkInProgressPrefix}}
</button>
{{end}}
</div>
{{end}}
{{if $data.MergeFormProps}}
{{/* The merge form is a Vue component. After mounted, it has a button for choosing merge style, so make it have min-height to avoid layout shifting */}}
<div class="item">
<div id="pull-request-merge-form" class="tw-min-h-[40px] tw-w-full" data-merge-form-props="{{JsonUtils.EncodeToString $data.MergeFormProps}}"></div>
</div>
{{end}}
{{if $data.ShowPullCommands}}
<div class="item">
{{template "repo/issue/view_content/pull_merge_instruction" dict "PullRequest" .Issue.PullRequest "MergeBoxData" $data}}
</div>
{{end}}
</div>
</div>
</div>
</div>
{{end}}
@@ -0,0 +1,64 @@
{{$data := $.MergeBoxData}}
{{$pull := $.PullRequest}}
<details>
<summary class="tw-pl-1">{{/* align with other item icon & text */}}
<span class="tw-pl-2">{{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}}</span>
</summary>
<div class="tw-my-[5px]">
<div>
<h3 class="tw-m-0">{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}</h3>
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}
</div>
{{$localBranch := $pull.HeadBranch}}
{{if ne $pull.HeadRepo.ID $pull.BaseRepo.ID}}
{{$localBranch = print $pull.HeadRepo.OwnerName "-" $pull.HeadBranch}}
{{end}}
<div class="ui secondary segment tw-font-mono">
{{$gitRemoteName := ctx.RootData.SystemConfig.Repository.GitGuideRemoteName.Value ctx}}
{{if eq $pull.Flow 0}}
<div>git fetch -u {{if ne $pull.HeadRepo.ID $pull.BaseRepo.ID}}{{ctx.AppFullLink $pull.HeadRepo.Link}}{{else}}{{$gitRemoteName}}{{end}} {{$pull.HeadBranch}}:{{$localBranch}}</div>
{{else}}
<div>git fetch -u {{$gitRemoteName}} {{$pull.GetGitHeadRefName}}:{{$localBranch}}</div>
{{end}}
<div>git checkout {{$localBranch}}</div>
</div>
{{if $data.ShowMergeInstructions}}
<div>
<h3 class="tw-m-0">{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3>
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}}
{{if not $data.AutodetectManualMerge}}
<div>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}</div>
{{end}}
</div>
<div class="ui secondary segment tw-font-mono">
<div data-pull-merge-style="merge">
<div>git checkout {{$pull.BaseBranch}}</div>
<div>git merge --no-ff {{$localBranch}}</div>
</div>
<div class="tw-hidden" data-pull-merge-style="rebase">
<div>git checkout {{$pull.BaseBranch}}</div>
<div>git merge --ff-only {{$localBranch}}</div>
</div>
<div class="tw-hidden" data-pull-merge-style="rebase-merge">
<div>git checkout {{$localBranch}}</div>
<div>git rebase {{$pull.BaseBranch}}</div>
<div>git checkout {{$pull.BaseBranch}}</div>
<div>git merge --no-ff {{$localBranch}}</div>
</div>
<div class="tw-hidden" data-pull-merge-style="squash">
<div>git checkout {{$pull.BaseBranch}}</div>
<div>git merge --squash {{$localBranch}}</div>
</div>
<div class="tw-hidden" data-pull-merge-style="fast-forward-only">
<div>git checkout {{$pull.BaseBranch}}</div>
<div>git merge --ff-only {{$localBranch}}</div>
</div>
<div class="tw-hidden" data-pull-merge-style="manually-merged">
<div>git checkout {{$pull.BaseBranch}}</div>
<div>git merge {{$localBranch}}</div>
</div>
<div>git push {{$gitRemoteName}} {{$pull.BaseBranch}}</div>
</div>
{{end}}
</div>
</details>
@@ -0,0 +1,34 @@
{{/* Template Attributes:
* StatusCheckData: see backend pullCommitStatusCheckData struct
*/}}
{{$statusCheckData := $.StatusCheckData}}
{{if $statusCheckData}}
{{$commitStatuses := $statusCheckData.PullCommitStatuses}}
<div class="item flex-left-right commit-status-toggle">
<div>{{$statusCheckData.CommitStatusCheckPrompt ctx.Locale}}</div>
<button data-global-click="onCommitStatusChecksToggle" class="btn interact-fg"
data-show-all="{{ctx.Locale.Tr "repo.pulls.status_checks_show_all"}}"
data-hide-all="{{ctx.Locale.Tr "repo.pulls.status_checks_hide_all"}}"
>{{ctx.Locale.Tr "repo.pulls.status_checks_hide_all"}}</button>
</div>
{{if $statusCheckData.RequireApprovalRunCount}}
<div class="item flex-left-right" id="approve-status-checks">
<div>
<strong>{{ctx.Locale.Tr "repo.pulls.status_checks_need_approvals" $statusCheckData.RequireApprovalRunCount}}</strong>
<p>{{ctx.Locale.Tr "repo.pulls.status_checks_need_approvals_helper"}}</p>
</div>
{{if $statusCheckData.CanApprove}}
<button class="ui basic button link-action" data-url="{{$statusCheckData.ApproveLink}}">
{{ctx.Locale.Tr "repo.pulls.status_checks_approve_all"}}
</button>
{{end}}
</div>
{{end}}
<div class="item tw-p-0">
<div class="commit-status-list flex-divided-list items-px-default">
{{template "repo/pulls/status_items" (dict "CommitStatuses" $commitStatuses "StatusCheckData" $statusCheckData)}}
</div>
</div>
{{end}}
@@ -0,0 +1,17 @@
<div class="bottom-reactions" data-action-url="{{$.ActionURL}}" role="group" aria-label="{{ctx.Locale.Tr "repo.reactions"}}">
{{range $key, $value := .Reactions}}
{{$hasReacted := $value.HasUser ctx.RootData.SignedUserID}}
<a role="button" class="ui label basic{{if $hasReacted}} primary{{end}}{{if not ctx.RootData.IsSigned}} disabled{{end}}"
data-global-click="onCommentReactionButtonClick"
data-tooltip-content title="{{$value.GetFirstUsers}}{{if gt ($value.GetMoreUserCount) 0}} {{ctx.Locale.Tr "repo.reactions_more" $value.GetMoreUserCount}}{{end}}"
aria-label="{{$key}}: {{$value.GetFirstUsers}}{{if gt ($value.GetMoreUserCount) 0}} {{ctx.Locale.Tr "repo.reactions_more" $value.GetMoreUserCount}}{{end}}"
data-tooltip-placement="bottom-start"
data-reaction-content="{{$key}}" data-has-reacted="{{$hasReacted}}">
<span class="reaction">{{ReactionToEmoji $key}}</span>
<span class="reaction-count">{{len $value}}</span>
</a>
{{end}}
{{if AllowedReactions}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" .ActionURL}}
{{end}}
</div>
@@ -0,0 +1,27 @@
<div class="ui small modal" id="reference-issue-modal">
<div class="header">
{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}
</div>
<div class="content">
<form class="ui form form-fetch-action" action="{{.Repository.Link}}/issues/new" method="post">
<div class="field">
<label><strong>{{ctx.Locale.Tr "repository"}}</strong></label>
<div class="ui search selection dropdown issue_reference_repository_search ellipsis-text-items">
<div class="default text gt-ellipsis">{{.Repository.FullName}}</div>
<div class="menu"></div>
</div>
</div>
<div class="field">
<label><strong>{{ctx.Locale.Tr "repo.milestones.title"}}</strong></label>
<input name="title" value="" autofocus required maxlength="255" autocomplete="off">
</div>
<div class="field">
<label><strong>{{ctx.Locale.Tr "repo.issues.reference_issue.body"}}</strong></label>
<textarea name="content"></textarea>
</div>
<div class="flex-text-block tw-justify-end">
<button class="ui primary button">{{ctx.Locale.Tr "repo.issues.create"}}</button>
</div>
</form>
</div>
</div>
@@ -0,0 +1,10 @@
{{if and .ShowRole.IsPoster (not .IgnorePoster)}}
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.author_helper"}}">
{{ctx.Locale.Tr "repo.issues.author"}}
</div>
{{end}}
{{if .ShowRole.RoleInRepo}}
<div class="ui basic label role-label" data-tooltip-content="{{.ShowRole.RoleInRepo.LocaleHelper ctx.Locale}}">
{{.ShowRole.RoleInRepo.LocaleString ctx.Locale}}
</div>
{{end}}
@@ -0,0 +1,26 @@
<div class="issue-content-right ui segment" data-global-init="initRepoIssueSidebar">
{{template "repo/issue/branch_selector_field" $}}{{/* TODO: RemoveIssueRef: template "repo/issue/branch_selector_field" $*/}}
{{if .Issue.IsPull}}
{{template "repo/issue/sidebar/reviewer_list" $.IssuePageMetaData}}
{{template "repo/issue/sidebar/wip_switch" $}}
<div class="divider"></div>
{{end}}
{{template "repo/issue/sidebar/label_list" $.IssuePageMetaData}}
{{template "repo/issue/sidebar/milestone_list" $.IssuePageMetaData}}
{{if .IsProjectsEnabled}}
{{template "repo/issue/sidebar/project_list" $.IssuePageMetaData}}
{{end}}
{{template "repo/issue/sidebar/assignee_list" $.IssuePageMetaData}}
{{template "repo/issue/sidebar/participant_list" $}}
{{template "repo/issue/sidebar/watch_notification" $}}
{{template "repo/issue/sidebar/stopwatch_timetracker" $}}
{{template "repo/issue/sidebar/due_date" $}}
{{template "repo/issue/sidebar/issue_dependencies" $}}
{{template "repo/issue/sidebar/reference_link" $}}
{{template "repo/issue/sidebar/issue_management" $}}
{{template "repo/issue/sidebar/allow_maintainer_edit" $}}
</div>
@@ -0,0 +1,24 @@
{{$data := $.MergeBoxData}}
<div class="tw-w-full flex-left-right">
<div class="flex-text-block">
{{svg "octicon-alert"}}
{{ctx.Locale.Tr "repo.pulls.outdated_with_base_branch"}}
</div>
{{if $data.UpdatePrimaryAction}}
<div class="ui buttons"{{if $data.UpdateStyleOptions}} data-global-init="initRepoPullRequestUpdate"{{end}}>
<button class="ui button link-action" data-url="{{$data.UpdatePrimaryAction.URL}}">
{{$data.UpdatePrimaryAction.Text}}
</button>
{{if gt (len $data.UpdateStyleOptions) 1}}
<div class="ui dropdown icon button">
{{svg "octicon-triangle-down"}}
<div class="menu">
{{range $data.UpdateStyleOptions}}
<a class="item {{if .Selected}}selected{{end}}" data-update-url="{{.URL}}">{{.Text}}</a>
{{end}}
</div>
</div>
{{end}}
</div>
{{end}}
</div>
@@ -0,0 +1,7 @@
<button class="fluid ui button" type="button" data-fetch-method="post" data-fetch-url="{{.Issue.Link}}/watch?watch={{not $.IssueWatch.IsWatching}}">
{{if $.IssueWatch.IsWatching}}
{{svg "octicon-mute" 16}} {{ctx.Locale.Tr "repo.issues.unsubscribe"}}
{{else}}
{{svg "octicon-unmute" 16}} {{ctx.Locale.Tr "repo.issues.subscribe"}}
{{end}}
</button>