mirror of
https://github.com/go-gitea/gitea
synced 2025-08-04 08:38:37 +00:00
Add mention, read/unread support of issue tracker
This commit is contained in:
@@ -152,7 +152,7 @@ func Repositories(ctx *middleware.Context) {
|
||||
ctx.Data["PageIsRepos"] = true
|
||||
|
||||
var err error
|
||||
ctx.Data["Repos"], err = models.GetRepos(200, 0)
|
||||
ctx.Data["Repos"], err = models.GetRepositoriesWithUsers(200, 0)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "admin.Repositories", err)
|
||||
return
|
||||
|
@@ -65,22 +65,27 @@ func Issues(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var pairs []*models.IssseUser
|
||||
if filterMode == models.FM_MENTION {
|
||||
// Get issue-user pairs.
|
||||
pairs, err = models.GetIssueUserPairs(ctx.Repo.Repository.Id, ctx.User.Id, isShowClosed)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "issue.Issues(GetIssueUserPairs): %v", err)
|
||||
return
|
||||
}
|
||||
// Get issue-user pairs.
|
||||
pairs, err := models.GetIssueUserPairs(ctx.Repo.Repository.Id, ctx.User.Id, isShowClosed)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "issue.Issues(GetIssueUserPairs): %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get posters.
|
||||
for i := range issues {
|
||||
if filterMode == models.FM_MENTION && !models.PairsContains(pairs, issues[i].Id) {
|
||||
idx := models.PairsContains(pairs, issues[i].Id)
|
||||
|
||||
if filterMode == models.FM_MENTION && (idx == -1 || !pairs[idx].IsMentioned) {
|
||||
continue
|
||||
}
|
||||
|
||||
if idx > -1 {
|
||||
issues[i].IsRead = pairs[idx].IsRead
|
||||
} else {
|
||||
issues[i].IsRead = true
|
||||
}
|
||||
|
||||
if err = issues[i].GetPoster(); err != nil {
|
||||
ctx.Handle(500, "issue.Issues(GetPoster): %v", err)
|
||||
return
|
||||
@@ -135,6 +140,24 @@ func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.C
|
||||
if err := models.NewIssue(issue); err != nil {
|
||||
ctx.Handle(500, "issue.CreateIssue(NewIssue)", err)
|
||||
return
|
||||
} else if err := models.NewIssueUserPairs(issue.RepoId, issue.Id,
|
||||
ctx.Repo.Owner.Id, ctx.User.Id, form.AssigneeId); err != nil {
|
||||
ctx.Handle(500, "issue.CreateIssue(NewIssueUserPairs)", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update mentions.
|
||||
ms := base.MentionPattern.FindAllString(issue.Content, -1)
|
||||
if len(ms) > 0 {
|
||||
for i := range ms {
|
||||
ms[i] = ms[i][1:]
|
||||
}
|
||||
|
||||
ids := models.GetUserIdsByNames(ms)
|
||||
if err := models.UpdateIssueUserPairsByMentions(ids, issue.Id); err != nil {
|
||||
ctx.Handle(500, "issue.CreateIssue(UpdateIssueUserPairsByMentions)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Notify watchers.
|
||||
@@ -154,14 +177,13 @@ func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.C
|
||||
}
|
||||
|
||||
tos = append(tos, ctx.User.LowerName)
|
||||
ms := base.MentionPattern.FindAllString(issue.Content, -1)
|
||||
newTos := make([]string, 0, len(ms))
|
||||
for _, m := range ms {
|
||||
if com.IsSliceContainsStr(tos, m[1:]) {
|
||||
if com.IsSliceContainsStr(tos, m) {
|
||||
continue
|
||||
}
|
||||
|
||||
newTos = append(newTos, m[1:])
|
||||
newTos = append(newTos, m)
|
||||
}
|
||||
if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner,
|
||||
ctx.Repo.Repository, issue, models.GetUserEmailsByNames(newTos)); err != nil {
|
||||
@@ -191,6 +213,12 @@ func ViewIssue(ctx *middleware.Context, params martini.Params) {
|
||||
return
|
||||
}
|
||||
|
||||
// Update issue-user.
|
||||
if err = models.UpdateIssueUserPairByRead(ctx.User.Id, issue.Id); err != nil {
|
||||
ctx.Handle(500, "issue.ViewIssue(UpdateIssueUserPairByRead): %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get poster.
|
||||
u, err := models.GetUserById(issue.PosterId)
|
||||
if err != nil {
|
||||
@@ -294,7 +322,10 @@ func Comment(ctx *middleware.Context, params martini.Params) {
|
||||
(strings.Contains(newStatus, "Close") && !issue.IsClosed) {
|
||||
issue.IsClosed = !issue.IsClosed
|
||||
if err = models.UpdateIssue(issue); err != nil {
|
||||
ctx.Handle(200, "issue.Comment(update issue status)", err)
|
||||
ctx.Handle(500, "issue.Comment(UpdateIssue)", err)
|
||||
return
|
||||
} else if err = models.UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
|
||||
ctx.Handle(500, "issue.Comment(UpdateIssueUserPairsByStatus)", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -311,6 +342,7 @@ func Comment(ctx *middleware.Context, params martini.Params) {
|
||||
}
|
||||
}
|
||||
|
||||
var ms []string
|
||||
content := ctx.Query("content")
|
||||
if len(content) > 0 {
|
||||
switch params["action"] {
|
||||
@@ -319,6 +351,21 @@ func Comment(ctx *middleware.Context, params martini.Params) {
|
||||
ctx.Handle(500, "issue.Comment(create comment)", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update mentions.
|
||||
ms = base.MentionPattern.FindAllString(issue.Content, -1)
|
||||
if len(ms) > 0 {
|
||||
for i := range ms {
|
||||
ms[i] = ms[i][1:]
|
||||
}
|
||||
|
||||
ids := models.GetUserIdsByNames(ms)
|
||||
if err := models.UpdateIssueUserPairsByMentions(ids, issue.Id); err != nil {
|
||||
ctx.Handle(500, "issue.CreateIssue(UpdateIssueUserPairsByMentions)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("%s Comment created: %d", ctx.Req.RequestURI, issue.Id)
|
||||
default:
|
||||
ctx.Handle(404, "issue.Comment", err)
|
||||
@@ -344,14 +391,13 @@ func Comment(ctx *middleware.Context, params martini.Params) {
|
||||
}
|
||||
|
||||
tos = append(tos, ctx.User.LowerName)
|
||||
ms := base.MentionPattern.FindAllString(issue.Content, -1)
|
||||
newTos := make([]string, 0, len(ms))
|
||||
for _, m := range ms {
|
||||
if com.IsSliceContainsStr(tos, m[1:]) {
|
||||
if com.IsSliceContainsStr(tos, m) {
|
||||
continue
|
||||
}
|
||||
|
||||
newTos = append(newTos, m[1:])
|
||||
newTos = append(newTos, m)
|
||||
}
|
||||
if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner,
|
||||
ctx.Repo.Repository, issue, models.GetUserEmailsByNames(newTos)); err != nil {
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
@@ -127,102 +128,94 @@ func Issues(ctx *middleware.Context) {
|
||||
}
|
||||
_, _ = assigneeId, posterId
|
||||
|
||||
// page, _ := base.StrTo(ctx.Query("page")).Int()
|
||||
// repoId, _ := base.StrTo(ctx.Query("repoid")).Int64()
|
||||
|
||||
// ctx.Data["RepoId"] = repoId
|
||||
|
||||
// var posterId int64 = 0
|
||||
// if ctx.Query("type") == "created_by" {
|
||||
// posterId = ctx.User.Id
|
||||
// ctx.Data["ViewType"] = "created_by"
|
||||
// }
|
||||
|
||||
rid, _ := base.StrTo(ctx.Query("repoid")).Int64()
|
||||
issueStats := models.GetUserIssueStats(ctx.User.Id, filterMode)
|
||||
|
||||
// Get all repositories.
|
||||
repos, err := models.GetRepositories(ctx.User, true)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "user.Issues(get repositories)", err)
|
||||
ctx.Handle(500, "user.Issues(GetRepositories)", err)
|
||||
return
|
||||
}
|
||||
|
||||
rids := make([]int64, 0, len(repos))
|
||||
showRepos := make([]*models.Repository, 0, len(repos))
|
||||
|
||||
// Get all issues.
|
||||
// allIssues := make([]models.Issue, 0, 5*len(repos))
|
||||
for _, repo := range repos {
|
||||
if repo.NumIssues == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
rids = append(rids, repo.Id)
|
||||
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
|
||||
issueStats.AllCount += int64(repo.NumOpenIssues)
|
||||
|
||||
// switch filterMode{
|
||||
// case models.FM_ASSIGN:
|
||||
|
||||
// }
|
||||
|
||||
if isShowClosed {
|
||||
if repo.NumClosedIssues > 0 {
|
||||
if filterMode == models.FM_CREATE {
|
||||
repo.NumClosedIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.Id, isShowClosed))
|
||||
}
|
||||
showRepos = append(showRepos, repo)
|
||||
}
|
||||
} else {
|
||||
if repo.NumOpenIssues > 0 {
|
||||
if filterMode == models.FM_CREATE {
|
||||
repo.NumOpenIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.Id, isShowClosed))
|
||||
}
|
||||
showRepos = append(showRepos, repo)
|
||||
}
|
||||
}
|
||||
|
||||
// issues, err := models.GetIssues(0, repo.Id, posterId, 0, page, isShowClosed, "", "")
|
||||
// if err != nil {
|
||||
// ctx.Handle(200, "user.Issues(get issues)", err)
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
||||
// allIssueCount += repo.NumIssues
|
||||
// closedIssueCount += repo.NumClosedIssues
|
||||
if rid > 0 {
|
||||
rids = []int64{rid}
|
||||
}
|
||||
|
||||
// // Set repository information to issues.
|
||||
// for j := range issues {
|
||||
// issues[j].Repo = &repos[i]
|
||||
// }
|
||||
// allIssues = append(allIssues, issues...)
|
||||
page, _ := base.StrTo(ctx.Query("page")).Int()
|
||||
|
||||
// repos[i].NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
|
||||
// if repos[i].NumOpenIssues > 0 {
|
||||
// showRepos = append(showRepos, repos[i])
|
||||
// }
|
||||
// }
|
||||
// Get all issues.
|
||||
var ius []*models.IssueUser
|
||||
switch viewType {
|
||||
case "assigned":
|
||||
fallthrough
|
||||
case "created_by":
|
||||
ius, err = models.GetIssueUserPairsByMode(ctx.User.Id, rid, isShowClosed, page, filterMode)
|
||||
default:
|
||||
ius, err = models.GetIssueUserPairsByRepoIds(rids, isShowClosed, page)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Handle(500, "user.Issues(GetAllIssueUserPairs)", err)
|
||||
return
|
||||
}
|
||||
|
||||
// showIssues := make([]models.Issue, 0, len(allIssues))
|
||||
// ctx.Data["IsShowClosed"] = isShowClosed
|
||||
issues := make([]*models.Issue, len(ius))
|
||||
for i := range ius {
|
||||
issues[i], err = models.GetIssueById(ius[i].IssueId)
|
||||
if err != nil {
|
||||
if err == models.ErrIssueNotExist {
|
||||
log.Error("user.Issues(#%d): issue not exist", ius[i].IssueId)
|
||||
continue
|
||||
} else {
|
||||
ctx.Handle(500, "user.Issues(GetIssue)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// // Get posters and filter issues.
|
||||
// for i := range allIssues {
|
||||
// u, err := models.GetUserById(allIssues[i].PosterId)
|
||||
// if err != nil {
|
||||
// ctx.Handle(200, "user.Issues(get poster): %v", err)
|
||||
// return
|
||||
// }
|
||||
// allIssues[i].Poster = u
|
||||
// if u.Id == ctx.User.Id {
|
||||
// createdByCount++
|
||||
// }
|
||||
issues[i].Repo, err = models.GetRepositoryById(issues[i].RepoId)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "user.Issues(GetRepositoryById)", err)
|
||||
return
|
||||
}
|
||||
|
||||
// if repoId > 0 && repoId != allIssues[i].Repo.Id {
|
||||
// continue
|
||||
// }
|
||||
|
||||
// if isShowClosed == allIssues[i].IsClosed {
|
||||
// showIssues = append(showIssues, allIssues[i])
|
||||
// }
|
||||
// }
|
||||
issues[i].Poster, err = models.GetUserById(issues[i].PosterId)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "user.Issues(GetUserById)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["RepoId"] = rid
|
||||
ctx.Data["Repos"] = showRepos
|
||||
ctx.Data["Issues"] = issues
|
||||
ctx.Data["ViewType"] = viewType
|
||||
ctx.Data["IssueStats"] = issueStats
|
||||
ctx.Data["IsShowClosed"] = isShowClosed
|
||||
|
Reference in New Issue
Block a user