From 0a3c3357f388cc60d5f43a056ee2381e51586cff Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Sat, 16 Jan 2021 06:55:17 +0200 Subject: [PATCH 1/9] Sort issue search results by revelance (#14353) --- models/issue.go | 2 +- models/issue_test.go | 2 +- modules/indexer/issues/bleve.go | 1 + modules/indexer/issues/elastic_search.go | 2 +- modules/indexer/issues/indexer_test.go | 4 ++-- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/models/issue.go b/models/issue.go index b517f334c450a..7731a59ed0f4d 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1682,7 +1682,7 @@ func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int6 ) var ids = make([]int64, 0, limit) - err := x.Distinct("id").Table("issue").Where(cond).Limit(limit, start).Find(&ids) + err := x.Distinct("id").Table("issue").Where(cond).OrderBy("`updated_unix` DESC").Limit(limit, start).Find(&ids) if err != nil { return 0, nil, err } diff --git a/models/issue_test.go b/models/issue_test.go index 1f65cb433a80c..8fbc49a46dbea 100644 --- a/models/issue_test.go +++ b/models/issue_test.go @@ -299,7 +299,7 @@ func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { total, ids, err = SearchIssueIDsByKeyword("for", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 5, total) - assert.EqualValues(t, []int64{1, 2, 3, 5, 11}, ids) + assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) // issue1's comment id 2 total, ids, err = SearchIssueIDsByKeyword("good", []int64{1}, 10, 0) diff --git a/modules/indexer/issues/bleve.go b/modules/indexer/issues/bleve.go index a1f51dba50bff..4a1e2bc51b99c 100644 --- a/modules/indexer/issues/bleve.go +++ b/modules/indexer/issues/bleve.go @@ -247,6 +247,7 @@ func (b *BleveIndexer) Search(keyword string, repoIDs []int64, limit, start int) newMatchPhraseQuery(keyword, "Comments", issueIndexerAnalyzer), )) search := bleve.NewSearchRequestOptions(indexerQuery, limit, start, false) + search.SortBy([]string{"-_score"}) result, err := b.indexer.Search(search) if err != nil { diff --git a/modules/indexer/issues/elastic_search.go b/modules/indexer/issues/elastic_search.go index 4cdeff53dc17c..3af64ed30e535 100644 --- a/modules/indexer/issues/elastic_search.go +++ b/modules/indexer/issues/elastic_search.go @@ -205,7 +205,7 @@ func (b *ElasticSearchIndexer) Search(keyword string, repoIDs []int64, limit, st searchResult, err := b.client.Search(). Index(b.indexerName). Query(query). - Sort("id", true). + Sort("_score", false). From(start).Size(limit). Do(context.Background()) if err != nil { diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 95007d8fafc4c..8c163f78d15dd 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -65,7 +65,7 @@ func TestBleveSearchIssues(t *testing.T) { ids, err = SearchIssuesByKeyword([]int64{1}, "for") assert.NoError(t, err) - assert.EqualValues(t, []int64{1, 2, 3, 5, 11}, ids) + assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) ids, err = SearchIssuesByKeyword([]int64{1}, "good") assert.NoError(t, err) @@ -89,7 +89,7 @@ func TestDBSearchIssues(t *testing.T) { ids, err = SearchIssuesByKeyword([]int64{1}, "for") assert.NoError(t, err) - assert.EqualValues(t, []int64{1, 2, 3, 5, 11}, ids) + assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) ids, err = SearchIssuesByKeyword([]int64{1}, "good") assert.NoError(t, err) From 76fefd803fde5899022777dc9aef8bdc09472107 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 16 Jan 2021 04:56:29 +0000 Subject: [PATCH 2/9] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 9 +++++++++ options/locale/locale_tr-TR.ini | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 322f0c9c9a95f..af0b98515d59e 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -358,6 +358,7 @@ password_not_match=パスワードが一致しません。 lang_select_error=言語をリストから選択してください。 username_been_taken=ユーザー名が既に使用されています。 +username_change_not_local_user=非ローカルユーザーのユーザー名は変更できません。 repo_name_been_taken=リポジトリ名が既に使用されています。 repository_files_already_exist=このリポジトリのファイルはすでに存在します。システム管理者に問い合わせてください。 repository_files_already_exist.adopt=このリポジトリのファイルはすでに存在しており、それらを登録することしかできません。 @@ -821,6 +822,8 @@ tag=タグ released_this=がこれをリリース file_raw=Raw file_history=履歴 +file_view_source=ソースを表示 +file_view_rendered=レンダリング表示 file_view_raw=Rawデータを見る file_permalink=パーマリンク file_too_large=このファイルは大きすぎるため、表示できません。 @@ -1997,6 +2000,7 @@ dashboard=ダッシュボード users=ユーザーアカウント organizations=組織 repositories=リポジトリ +hooks=Webhook authentication=認証ソース emails=ユーザーメールアドレス config=設定 @@ -2146,8 +2150,13 @@ repos.forks=フォーク repos.issues=課題 repos.size=サイズ +defaulthooks=デフォルトWebhook +defaulthooks.desc=Webhookは、特定のGiteaイベントトリガーが発生した際に、自動的にHTTP POSTリクエストをサーバーへ送信するものです。 ここで定義されたWebhookはデフォルトとなり、全ての新規リポジトリにコピーされます。 詳しくはwebhooks guideをご覧下さい。 +defaulthooks.add_webhook=デフォルトWebhookの追加 +defaulthooks.update_webhook=デフォルトWebhookの更新 systemhooks=システムWebhook +systemhooks.desc=Webhookは、特定のGiteaイベントトリガーが発生した際に、自動的にHTTP POSTリクエストをサーバーへ送信するものです。 ここで定義したWebhookはシステム内のすべてのリポジトリで呼び出されます。 そのため、パフォーマンスに及ぼす影響を考慮したうえで設定してください。 詳しくはwebhooks guideをご覧下さい。 systemhooks.add_webhook=システムWebhookを追加 systemhooks.update_webhook=システムWebhookを更新 diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index e0f27905566f2..e5b2ad5759c5f 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -358,6 +358,7 @@ password_not_match=Parolalar uyuşmuyor. lang_select_error=Listeden bir dil seçin. username_been_taken=Bu kullanıcı adı daha önce alınmış. +username_change_not_local_user=Yerel olmayan kullanıcılar kendi kullanıcı adlarını değiştiremezler. repo_name_been_taken=Depo adı zaten kullanılıyor. repository_files_already_exist=Bu depo için dosyalar zaten var. Sistem yöneticisine başvurun. repository_files_already_exist.adopt=Bu depo için dosyalar zaten var ve yalnızca Kabul Edilebilir. @@ -821,6 +822,8 @@ tag=Etiket released_this=bu sürümü yayınladı file_raw=Ham file_history=Geçmiş +file_view_source=Kaynağı Görüntüle +file_view_rendered=Oluşturulanları Görüntüle file_view_raw=Ham Görünüm file_permalink=Kalıcı Bağlantı file_too_large=Bu dosya görüntülemek için çok büyük. @@ -941,6 +944,8 @@ projects.board.edit_title=Yeni Pano Adı projects.board.new_title=Yeni Pano Adı projects.board.new_submit=Gönder projects.board.new=Yeni Pano +projects.board.set_default=Varsayılana Ayarla +projects.board.set_default_desc=Kategorize edilmemiş konular ve çekme istekleri için bu panoyu varsayılan olarak ayarlayın projects.board.delete=Panoyu Sil projects.board.deletion_desc=Bir proje panosunun silinmesi, ilgili tüm konuları 'Kategorize edilmemiş'e taşır. Devam edilsin mi? projects.open=Aç @@ -1482,7 +1487,7 @@ settings.use_external_issue_tracker=Harici Konu İzleyici Kullan settings.external_tracker_url=Harici Konu İzleyici URLsi settings.external_tracker_url_error=Harici konu izleyici URL'si geçerli bir URL değil. settings.external_tracker_url_desc=Ziyaretçiler, konular sekmesine tıkladığında harici konu izleyici URL'sine yönlendirilir. -settings.tracker_url_format=Harici Sorun Takipçisi Bağlantı Formatı +settings.tracker_url_format=Harici Konu İzleyici URL Biçimi settings.tracker_url_format_error=Harici konu izleyici URL biçimi geçerli bir URL değil. settings.tracker_issue_style=Harici Konu İzleyici Numara Biçimi settings.tracker_issue_style.numeric=Sayısal @@ -1997,6 +2002,7 @@ dashboard=Pano users=Kullanıcı Hesapları organizations=Organizasyonlar repositories=Depolar +hooks=Web İstemcileri authentication=Yetkilendirme Kaynakları emails=Kullanıcı E-postaları config=Yapılandırma @@ -2084,7 +2090,7 @@ users.full_name=Tam İsim users.activated=Aktifleştirilmiş users.admin=Yönetici users.restricted=Kısıtlanmış -users.2fa=2ED +users.2fa=2FD users.repos=Depolar users.created=Oluşturuldu users.last_login=Son Oturum Açma @@ -2113,6 +2119,7 @@ users.delete_account=Kullanıcı Hesabını Sil users.still_own_repo=Bu kullanıcı hala bir veya daha fazla depoya sahip. Önce bu depoları silin veya transfer edin. users.still_has_org=Bu kullanıcı bir organizasyonun üyesidir. Önce kullanıcıyı tüm organizasyonlardan çıkarın. users.deletion_success=Kullanıcı hesabı silindi. +users.reset_2fa=2FD'yi sıfırla emails.email_manage_panel=Kullanıcı E-posta Yönetimi emails.primary=Birincil @@ -2145,8 +2152,13 @@ repos.forks=Çatallar repos.issues=Konular repos.size=Boyut +defaulthooks=Varsayılan Web İstemcileri +defaulthooks.desc=Web İstemcileri, belirli Gitea olayları tetiklendiğinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanımlanan Web İstemcileri varsayılandır ve tüm yeni depolara kopyalanır. web istemcileri kılavuzunda daha fazla bilgi edinin. +defaulthooks.add_webhook=Varsayılan Web İstemcisi Ekle +defaulthooks.update_webhook=Varsayılan Web İstemcisini Güncelle systemhooks=Sistem Web İstemcileri +systemhooks.desc=Belirli Gitea olayları tetiklendiğinde Web istemcileri otomatik olarak bir sunucuya HTTP POST istekleri yapar. Burada tanımlanan web istemcileri sistemdeki tüm depolar üzerinde çalışır, bu yüzden lütfen bunun olabilecek tüm performans sonuçlarını göz önünde bulundurun. web istemcileri kılavuzunda daha fazla bilgi edinin. systemhooks.add_webhook=Sistem Web İstemcisi Ekle systemhooks.update_webhook=Sistem Web İstemcisi Güncelle From dc66e4740f1d788e67f758ee3a6bbeb646ad704a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 16 Jan 2021 19:23:02 +0800 Subject: [PATCH 3/9] Fix middlewares sequences (#14354) Co-authored-by: 6543 <6543@obermui.de> --- routers/api/v1/api.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index e9f1a395ed980..02ad8ab3606d6 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -640,7 +640,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/:username/:reponame", func() { m.Combo("").Get(reqAnyRepoReader(), repo.Get). Delete(reqToken(), reqOwner(), repo.Delete). - Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), context.RepoRefForAPI(), repo.Edit) + Patch(reqToken(), reqAdmin(), context.RepoRefForAPI(), bind(api.EditRepoOption{}), repo.Edit) m.Post("/transfer", reqOwner(), bind(api.TransferRepoOption{}), repo.Transfer) m.Combo("/notifications"). Get(reqToken(), notify.ListRepoNotifications). @@ -713,8 +713,8 @@ func RegisterRoutes(m *macaron.Macaron) { Delete(reqToken(), repo.DeleteIssueComment) m.Combo("/reactions"). Get(repo.GetIssueCommentReactions). - Post(bind(api.EditReactionOption{}), reqToken(), repo.PostIssueCommentReaction). - Delete(bind(api.EditReactionOption{}), reqToken(), repo.DeleteIssueCommentReaction) + Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). + Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) }) }) m.Group("/:index", func() { @@ -754,8 +754,8 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Combo("/reactions"). Get(repo.GetIssueReactions). - Post(bind(api.EditReactionOption{}), reqToken(), repo.PostIssueReaction). - Delete(bind(api.EditReactionOption{}), reqToken(), repo.DeleteIssueReaction) + Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueReaction). + Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueReaction) }) }, mustEnableIssuesOrPulls) m.Group("/labels", func() { From e6155ff9b689872b3797fe1e2504e5919b0c4888 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 16 Jan 2021 11:24:18 +0000 Subject: [PATCH 4/9] [skip ci] Updated translations via Crowdin --- options/locale/locale_zh-TW.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 7625a5816946e..d23d8a9c1a1f1 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -943,6 +943,8 @@ projects.board.edit_title=新看板名稱 projects.board.new_title=新看板名稱 projects.board.new_submit=送出 projects.board.new=新增看板 +projects.board.set_default=設為預設 +projects.board.set_default_desc=將此看板設定為未分類問題及合併請求的預設看板 projects.board.delete=刪除看板 projects.board.deletion_desc=刪除專案看板會將相關的問題移動到 '未分類'。是否繼續? projects.open=開啟 From 4d9349123fb6102357c39a728c55d648a16be3b8 Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sun, 17 Jan 2021 15:15:57 +0100 Subject: [PATCH 5/9] label and milestone webhooks on issue/pull creation (#14363) --- services/issue/issue.go | 6 ++++++ services/pull/pull.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/services/issue/issue.go b/services/issue/issue.go index 14de0290a1b11..90f689a55cc3e 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -29,6 +29,12 @@ func NewIssue(repo *models.Repository, issue *models.Issue, labelIDs []int64, uu } notification.NotifyNewIssue(issue, mentions) + if len(issue.Labels) > 0 { + notification.NotifyIssueChangeLabels(issue.Poster, issue, issue.Labels, nil) + } + if issue.Milestone != nil { + notification.NotifyIssueChangeMilestone(issue.Poster, issue, 0) + } return nil } diff --git a/services/pull/pull.go b/services/pull/pull.go index 1886448ee0093..92f1ff65fb2fd 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -59,6 +59,12 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6 } notification.NotifyNewPullRequest(pr, mentions) + if len(pull.Labels) > 0 { + notification.NotifyIssueChangeLabels(pull.Poster, pull, pull.Labels, nil) + } + if pull.Milestone != nil { + notification.NotifyIssueChangeMilestone(pull.Poster, pull, 0) + } // add first push codes comment baseGitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) From 66e426b2f18dfa8806e89f3c225051dd1b3a37e2 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sun, 17 Jan 2021 14:17:10 +0000 Subject: [PATCH 6/9] [skip ci] Updated translations via Crowdin --- options/locale/locale_tr-TR.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index e5b2ad5759c5f..2beebac8b13e2 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -2501,6 +2501,7 @@ mirror_sync_delete=%[3]s adresindeki %[2]s refe approve_pull_request=`%s#%[2]s onaylandı` reject_pull_request=`%s#%[2]s için değişiklik önerdi ` publish_release=` %[3]s deposunda "%[4]s" sürümü yayınlandı` +create_branch=%[3]s dalını %[4]s içinde oluşturdu [tool] ago=%s önce From 872d3088920f8da2070f497f40d89d35fff9679f Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sun, 17 Jan 2021 15:57:42 +0100 Subject: [PATCH 7/9] escape branch names in compare url (#14364) --- routers/repo/editor.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/repo/editor.go b/routers/repo/editor.go index 7538c4cdaac2e..afb6605dc33c9 100644 --- a/routers/repo/editor.go +++ b/routers/repo/editor.go @@ -287,7 +287,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo } else if models.IsErrCommitIDDoesNotMatch(err) { ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+ctx.Repo.CommitID), tplEditFile, &form) } else if git.IsErrPushOutOfDate(err) { - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+form.NewBranchName), tplEditFile, &form) + ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+util.PathEscapeSegments(form.NewBranchName)), tplEditFile, &form) } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { @@ -319,7 +319,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo } if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) } @@ -500,7 +500,7 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) { ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath)) if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { treePath := filepath.Dir(ctx.Repo.TreePath) if treePath == "." { @@ -677,7 +677,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { branchErr := err.(models.ErrBranchAlreadyExists) ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplUploadFile, &form) } else if git.IsErrPushOutOfDate(err) { - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+ctx.Repo.CommitID+"..."+form.NewBranchName), tplUploadFile, &form) + ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+ctx.Repo.CommitID+"..."+util.PathEscapeSegments(form.NewBranchName)), tplUploadFile, &form) } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { @@ -703,7 +703,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { } if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) } From acb1ceb1f426e87e7f821c01ab5b60dad7abc03d Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sun, 17 Jan 2021 17:34:19 +0100 Subject: [PATCH 8/9] Add review requested filter on pull request overview (#13701) * Add review requested filter on pull request overview #13682 fix formatting * add review_requested filter to /repos/issues/search API endpoint * only Approve and Reject status should supersede Request status * add support for team reviews * refactor: remove duplication of issue filtering conditions --- models/issue.go | 159 +++++++++++++-------- options/locale/locale_en-US.ini | 1 + routers/api/v1/repo/issue.go | 9 +- routers/repo/issue.go | 53 +++---- routers/user/home.go | 6 +- templates/repo/issue/list.tmpl | 3 + templates/repo/issue/milestone_issues.tmpl | 1 + templates/swagger/v1_json.tmpl | 6 + templates/user/dashboard/issues.tmpl | 6 + 9 files changed, 156 insertions(+), 88 deletions(-) diff --git a/models/issue.go b/models/issue.go index 7731a59ed0f4d..3cd85dc6afcd8 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1090,6 +1090,7 @@ type IssuesOptions struct { AssigneeID int64 PosterID int64 MentionedID int64 + ReviewRequestedID int64 MilestoneIDs []int64 ProjectID int64 ProjectBoardID int64 @@ -1151,8 +1152,7 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } if len(opts.RepoIDs) > 0 { - // In case repository IDs are provided but actually no repository has issue. - sess.In("issue.repo_id", opts.RepoIDs) + applyReposCondition(sess, opts.RepoIDs) } switch opts.IsClosed { @@ -1163,18 +1163,19 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } if opts.AssigneeID > 0 { - sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.AssigneeID) + applyAssigneeCondition(sess, opts.AssigneeID) } if opts.PosterID > 0 { - sess.And("issue.poster_id=?", opts.PosterID) + applyPosterCondition(sess, opts.PosterID) } if opts.MentionedID > 0 { - sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). - And("issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.MentionedID) + applyMentionedCondition(sess, opts.MentionedID) + } + + if opts.ReviewRequestedID > 0 { + applyReviewRequestedCondition(sess, opts.ReviewRequestedID) } if len(opts.MilestoneIDs) > 0 { @@ -1232,6 +1233,33 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } } +func applyReposCondition(sess *xorm.Session, repoIDs []int64) *xorm.Session { + return sess.In("issue.repo_id", repoIDs) +} + +func applyAssigneeCondition(sess *xorm.Session, assigneeID int64) *xorm.Session { + return sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). + And("issue_assignees.assignee_id = ?", assigneeID) +} + +func applyPosterCondition(sess *xorm.Session, posterID int64) *xorm.Session { + return sess.And("issue.poster_id=?", posterID) +} + +func applyMentionedCondition(sess *xorm.Session, mentionedID int64) *xorm.Session { + return sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). + And("issue_user.is_mentioned = ?", true). + And("issue_user.uid = ?", mentionedID) +} + +func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64) *xorm.Session { + return sess.Join("INNER", []string{"review", "r"}, "issue.id = r.issue_id"). + And("r.type = ?", ReviewTypeRequest). + And("r.reviewer_id = ? and r.id in (select max(id) from review where issue_id = r.issue_id and reviewer_id = r.reviewer_id and type in (?, ?, ?))"+ + " or r.reviewer_team_id in (select team_id from team_user where uid = ?)", + reviewRequestedID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, reviewRequestedID) +} + // CountIssuesByRepo map from repoID to number of issues matching the options func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) { sess := x.NewSession() @@ -1364,6 +1392,7 @@ type IssueStats struct { AssignCount int64 CreateCount int64 MentionCount int64 + ReviewRequestedCount int64 } // Filter modes. @@ -1372,6 +1401,7 @@ const ( FilterModeAssign FilterModeCreate FilterModeMention + FilterModeReviewRequested ) func parseCountResult(results []map[string][]byte) int64 { @@ -1387,14 +1417,15 @@ func parseCountResult(results []map[string][]byte) int64 { // IssueStatsOptions contains parameters accepted by GetIssueStats. type IssueStatsOptions struct { - RepoID int64 - Labels string - MilestoneID int64 - AssigneeID int64 - MentionedID int64 - PosterID int64 - IsPull util.OptionalBool - IssueIDs []int64 + RepoID int64 + Labels string + MilestoneID int64 + AssigneeID int64 + MentionedID int64 + PosterID int64 + ReviewRequestedID int64 + IsPull util.OptionalBool + IssueIDs []int64 } // GetIssueStats returns issue statistic information by given conditions. @@ -1423,6 +1454,7 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { accum.AssignCount += stats.AssignCount accum.CreateCount += stats.CreateCount accum.OpenCount += stats.MentionCount + accum.ReviewRequestedCount += stats.ReviewRequestedCount i = chunk } return accum, nil @@ -1460,18 +1492,19 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, } if opts.AssigneeID > 0 { - sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.AssigneeID) + applyAssigneeCondition(sess, opts.AssigneeID) } if opts.PosterID > 0 { - sess.And("issue.poster_id = ?", opts.PosterID) + applyPosterCondition(sess, opts.PosterID) } if opts.MentionedID > 0 { - sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). - And("issue_user.uid = ?", opts.MentionedID). - And("issue_user.is_mentioned = ?", true) + applyMentionedCondition(sess, opts.MentionedID) + } + + if opts.ReviewRequestedID > 0 { + applyReviewRequestedCondition(sess, opts.ReviewRequestedID) } switch opts.IsPull { @@ -1539,57 +1572,66 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) { switch opts.FilterMode { case FilterModeAll: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - And(builder.In("issue.repo_id", opts.UserRepoIDs)). + stats.OpenCount, err = applyReposCondition(sess(cond), opts.UserRepoIDs). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - And(builder.In("issue.repo_id", opts.UserRepoIDs)). + stats.ClosedCount, err = applyReposCondition(sess(cond), opts.UserRepoIDs). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err } case FilterModeAssign: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.UserID). + stats.OpenCount, err = applyAssigneeCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.UserID). + stats.ClosedCount, err = applyAssigneeCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err } case FilterModeCreate: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - And("issue.poster_id = ?", opts.UserID). + stats.OpenCount, err = applyPosterCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - And("issue.poster_id = ?", opts.UserID). + stats.ClosedCount, err = applyPosterCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err } case FilterModeMention: - stats.OpenCount, err = sess(cond).And("issue.is_closed = ?", false). - Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.UserID). + stats.OpenCount, err = applyMentionedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return nil, err } - stats.ClosedCount, err = sess(cond).And("issue.is_closed = ?", true). - Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.UserID). + stats.ClosedCount, err = applyMentionedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). + Count(new(Issue)) + if err != nil { + return nil, err + } + case FilterModeReviewRequested: + stats.OpenCount, err = applyReviewRequestedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", false). + Count(new(Issue)) + if err != nil { + return nil, err + } + stats.ClosedCount, err = applyReviewRequestedCondition(sess(cond), opts.UserID). + And("issue.is_closed = ?", true). Count(new(Issue)) if err != nil { return nil, err @@ -1597,32 +1639,27 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) { } cond = cond.And(builder.Eq{"issue.is_closed": opts.IsClosed}) - stats.AssignCount, err = sess(cond). - Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", opts.UserID). - Count(new(Issue)) + stats.AssignCount, err = applyAssigneeCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } - stats.CreateCount, err = sess(cond). - And("poster_id = ?", opts.UserID). - Count(new(Issue)) + stats.CreateCount, err = applyPosterCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } - stats.MentionCount, err = sess(cond). - Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true). - And("issue_user.uid = ?", opts.UserID). - Count(new(Issue)) + stats.MentionCount, err = applyMentionedCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } - stats.YourRepositoriesCount, err = sess(cond). - And(builder.In("issue.repo_id", opts.UserRepoIDs)). - Count(new(Issue)) + stats.YourRepositoriesCount, err = applyReposCondition(sess(cond), opts.UserRepoIDs).Count(new(Issue)) + if err != nil { + return nil, err + } + + stats.ReviewRequestedCount, err = applyReviewRequestedCondition(sess(cond), opts.UserID).Count(new(Issue)) if err != nil { return nil, err } @@ -1646,13 +1683,11 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen switch filterMode { case FilterModeAssign: - openCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", uid) - closedCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", uid) + applyAssigneeCondition(openCountSession, uid) + applyAssigneeCondition(closedCountSession, uid) case FilterModeCreate: - openCountSession.And("poster_id = ?", uid) - closedCountSession.And("poster_id = ?", uid) + applyPosterCondition(openCountSession, uid) + applyPosterCondition(closedCountSession, uid) } openResult, _ := openCountSession.Count(new(Issue)) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4546a06e81803..73451eeebb136 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1030,6 +1030,7 @@ issues.filter_type.all_issues = All issues issues.filter_type.assigned_to_you = Assigned to you issues.filter_type.created_by_you = Created by you issues.filter_type.mentioning_you = Mentioning you +issues.filter_type.review_requested = Review requested issues.filter_sort = Sort issues.filter_sort.latest = Newest issues.filter_sort.oldest = Oldest diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 25153ad50773c..bab8f373ce271 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -79,6 +79,10 @@ func SearchIssues(ctx *context.APIContext) { // in: query // description: filter (issues / pulls) mentioning you, default is false // type: boolean + // - name: review_requested + // in: query + // description: filter pulls requesting your review, default is false + // type: boolean // - name: page // in: query // description: page number of results to return (1-based) @@ -204,7 +208,7 @@ func SearchIssues(ctx *context.APIContext) { UpdatedAfterUnix: since, } - // Filter for: Created by User, Assigned to User, Mentioning User + // Filter for: Created by User, Assigned to User, Mentioning User, Review of User Requested if ctx.QueryBool("created") { issuesOpt.PosterID = ctx.User.ID } @@ -214,6 +218,9 @@ func SearchIssues(ctx *context.APIContext) { if ctx.QueryBool("mentioned") { issuesOpt.MentionedID = ctx.User.ID } + if ctx.QueryBool("review_requested") { + issuesOpt.ReviewRequestedID = ctx.User.ID + } if issues, err = models.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 478baf8d86aa8..7b4044ac7b81b 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -113,16 +113,17 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti var err error viewType := ctx.Query("type") sortType := ctx.Query("sort") - types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned"} + types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested"} if !util.IsStringInSlice(viewType, types, true) { viewType = "all" } var ( - assigneeID = ctx.QueryInt64("assignee") - posterID int64 - mentionedID int64 - forceEmpty bool + assigneeID = ctx.QueryInt64("assignee") + posterID int64 + mentionedID int64 + reviewRequestedID int64 + forceEmpty bool ) if ctx.IsSigned { @@ -133,6 +134,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti mentionedID = ctx.User.ID case "assigned": assigneeID = ctx.User.ID + case "review_requested": + reviewRequestedID = ctx.User.ID } } @@ -169,14 +172,15 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti issueStats = &models.IssueStats{} } else { issueStats, err = models.GetIssueStats(&models.IssueStatsOptions{ - RepoID: repo.ID, - Labels: selectLabels, - MilestoneID: milestoneID, - AssigneeID: assigneeID, - MentionedID: mentionedID, - PosterID: posterID, - IsPull: isPullOption, - IssueIDs: issueIDs, + RepoID: repo.ID, + Labels: selectLabels, + MilestoneID: milestoneID, + AssigneeID: assigneeID, + MentionedID: mentionedID, + PosterID: posterID, + ReviewRequestedID: reviewRequestedID, + IsPull: isPullOption, + IssueIDs: issueIDs, }) if err != nil { ctx.ServerError("GetIssueStats", err) @@ -217,17 +221,18 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti Page: pager.Paginater.Current(), PageSize: setting.UI.IssuePagingNum, }, - RepoIDs: []int64{repo.ID}, - AssigneeID: assigneeID, - PosterID: posterID, - MentionedID: mentionedID, - MilestoneIDs: mileIDs, - ProjectID: projectID, - IsClosed: util.OptionalBoolOf(isShowClosed), - IsPull: isPullOption, - LabelIDs: labelIDs, - SortType: sortType, - IssueIDs: issueIDs, + RepoIDs: []int64{repo.ID}, + AssigneeID: assigneeID, + PosterID: posterID, + MentionedID: mentionedID, + ReviewRequestedID: reviewRequestedID, + MilestoneIDs: mileIDs, + ProjectID: projectID, + IsClosed: util.OptionalBoolOf(isShowClosed), + IsPull: isPullOption, + LabelIDs: labelIDs, + SortType: sortType, + IssueIDs: issueIDs, }) if err != nil { ctx.ServerError("Issues", err) diff --git a/routers/user/home.go b/routers/user/home.go index 3c27bbe2a8dcd..a8a8a5f3d7503 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -392,6 +392,8 @@ func buildIssueOverview(ctx *context.Context, unitType models.UnitType) { filterMode = models.FilterModeCreate case "mentioned": filterMode = models.FilterModeMention + case "review_requested": + filterMode = models.FilterModeReviewRequested case "your_repositories": // filterMode already set to All default: viewType = "your_repositories" @@ -431,7 +433,9 @@ func buildIssueOverview(ctx *context.Context, unitType models.UnitType) { case models.FilterModeCreate: opts.PosterID = ctx.User.ID case models.FilterModeMention: - opts.MentionedID = ctx.User.ID + opts.MentionedID = ctxUser.ID + case models.FilterModeReviewRequested: + opts.ReviewRequestedID = ctxUser.ID } if ctxUser.IsOrganization() { diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index 2b64d26700628..7b856e60cb6cb 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -89,6 +89,9 @@ {{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}} {{.i18n.Tr "repo.issues.filter_type.created_by_you"}} {{.i18n.Tr "repo.issues.filter_type.mentioning_you"}} + {{if .PageIsPullList}} + {{.i18n.Tr "repo.issues.filter_type.review_requested"}} + {{end}} {{end}} diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index 638134c442620..c2c81682ff0ff 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -88,6 +88,7 @@ {{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}} {{.i18n.Tr "repo.issues.filter_type.created_by_you"}} {{.i18n.Tr "repo.issues.filter_type.mentioning_you"}} + {{.i18n.Tr "repo.issues.filter_type.review_requested"}} {{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 81ccf4f725346..6650c09bb44b7 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1911,6 +1911,12 @@ "name": "mentioned", "in": "query" }, + { + "type": "boolean", + "description": "filter pulls requesting your review, default is false", + "name": "review_requested", + "in": "query" + }, { "type": "integer", "description": "page number of results to return (1-based)", diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl index 62428dce42302..dfd0e5d8ec32a 100644 --- a/templates/user/dashboard/issues.tmpl +++ b/templates/user/dashboard/issues.tmpl @@ -21,6 +21,12 @@ {{.i18n.Tr "repo.issues.filter_type.mentioning_you"}} {{CountFmt .IssueStats.MentionCount}} + {{if .PageIsPulls}} + + {{.i18n.Tr "repo.issues.filter_type.review_requested"}} + {{CountFmt .IssueStats.ReviewRequestedCount}} + + {{end}}
All From ca63a9d3f1120d8c76eb83ff1fd07e0992a683a8 Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Sun, 17 Jan 2021 19:29:10 +0200 Subject: [PATCH 9/9] Add edit, delete and reaction support to code review comments on issue page (#14339) --- routers/repo/issue.go | 19 ++++++ templates/repo/diff/comments.tmpl | 2 +- .../repo/issue/view_content/comments.tmpl | 63 ++++++++++++++----- .../repo/issue/view_content/context_menu.tmpl | 6 +- web_src/less/_repository.less | 31 +++++++++ 5 files changed, 101 insertions(+), 20 deletions(-) diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 7b4044ac7b81b..6a532dc125a92 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -1377,7 +1377,26 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("Review.LoadCodeComments", err) return } + for _, codeComments := range comment.Review.CodeComments { + for _, lineComments := range codeComments { + for _, c := range lineComments { + // Check tag. + tag, ok = marked[c.PosterID] + if ok { + c.ShowTag = tag + continue + } + c.ShowTag, err = commentTag(repo, c.Poster, issue) + if err != nil { + ctx.ServerError("commentTag", err) + return + } + marked[c.PosterID] = c.ShowTag + participants = addParticipant(c.Poster, participants) + } + } + } if err = comment.LoadResolveDoer(); err != nil { ctx.ServerError("LoadResolveDoer", err) return diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index 59bc89b79e8ef..36e7259360b43 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -47,7 +47,7 @@ {{end}} {{end}} {{template "repo/issue/view_content/add_reaction" Dict "ctx" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) }} - {{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}} + {{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 8f5426b83e86f..abf5792a9ee1c 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -58,7 +58,7 @@
{{end}} {{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} - {{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} + {{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} {{end}} @@ -494,25 +494,49 @@ {{end}} -
+
{{range $comms}} {{ $createdSubStr:= TimeSinceUnix .CreatedUnix $.Lang }}
- {{if not .OriginalAuthor }} - - {{avatar .Poster}} - - {{end}}
- - {{if .OriginalAuthor }} - {{ .OriginalAuthor }} {{if $.Repository.OriginalURL}}({{$.i18n.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname | Safe }}){{end}} - {{else}} - {{.Poster.GetDisplayName}} - {{end}} - {{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdSubStr | Safe}} - +
+
+ {{if not .OriginalAuthor }} + + {{avatar .Poster}} + + {{end}} + + {{if .OriginalAuthor }} + {{ .OriginalAuthor }} {{if $.Repository.OriginalURL}}({{$.i18n.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname | Safe }}){{end}} + {{else}} + {{.Poster.GetDisplayName}} + {{end}} + {{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdSubStr | Safe}} + +
+
+ {{if not $.Repository.IsArchived}} + {{if or (and (eq .PosterID $.Issue.PosterID) (eq $.Issue.OriginalAuthorID 0)) (eq $.Issue.OriginalAuthorID .OriginalAuthorID) }} +
+ {{$.i18n.Tr "repo.issues.poster"}} +
+ {{end}} + {{if gt .ShowTag 0}} +
+ {{if eq .ShowTag 2}} + {{$.i18n.Tr "repo.issues.collaborator"}} + {{else if eq .ShowTag 3}} + {{$.i18n.Tr "repo.issues.owner"}} + {{end}} +
+ {{end}} + {{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} + {{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} + {{end}} +
+
{{if .RenderedContent}} @@ -521,8 +545,15 @@ {{$.i18n.Tr "repo.issues.no_content"}} {{end}}
-
{{.Content}}
+
{{.Content}}
+
+ {{$reactions := .Reactions.GroupByType}} + {{if $reactions}} +
+ {{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} +
+ {{end}}
{{end}} diff --git a/templates/repo/issue/view_content/context_menu.tmpl b/templates/repo/issue/view_content/context_menu.tmpl index 744821cb3c4d6..0b8b84e9f1a99 100644 --- a/templates/repo/issue/view_content/context_menu.tmpl +++ b/templates/repo/issue/view_content/context_menu.tmpl @@ -4,10 +4,10 @@ {{svg "octicon-kebab-horizontal"}}