diff options
Diffstat (limited to 'routers')
-rw-r--r-- | routers/repo/issue.go | 157 | ||||
-rw-r--r-- | routers/routes/routes.go | 2 |
2 files changed, 156 insertions, 3 deletions
diff --git a/routers/repo/issue.go b/routers/repo/issue.go index b45d521e5b..884a805180 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -39,6 +39,8 @@ const ( tplMilestoneNew base.TplName = "repo/issue/milestone_new" tplMilestoneEdit base.TplName = "repo/issue/milestone_edit" + tplReactions base.TplName = "repo/issue/view_content/reactions" + issueTemplateKey = "IssueTemplate" ) @@ -726,9 +728,8 @@ func GetActionIssue(ctx *context.Context) *models.Issue { ctx.NotFoundOrServerError("GetIssueByIndex", models.IsErrIssueNotExist, err) return nil } - if issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) || - !issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) { - ctx.Handle(404, "IssueOrPullRequestUnitNotAllowed", nil) + checkIssueRights(ctx, issue) + if ctx.Written() { return nil } if err = issue.LoadAttributes(); err != nil { @@ -738,6 +739,13 @@ func GetActionIssue(ctx *context.Context) *models.Issue { return issue } +func checkIssueRights(ctx *context.Context, issue *models.Issue) { + if issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) || + !issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) { + ctx.Handle(404, "IssueOrPullRequestUnitNotAllowed", nil) + } +} + func getActionIssues(ctx *context.Context) []*models.Issue { commaSeparatedIssueIDs := ctx.Query("issue_ids") if len(commaSeparatedIssueIDs) == 0 { @@ -1259,3 +1267,146 @@ func DeleteMilestone(ctx *context.Context) { "redirect": ctx.Repo.RepoLink + "/milestones", }) } + +// ChangeIssueReaction create a reaction for issue +func ChangeIssueReaction(ctx *context.Context, form auth.ReactionForm) { + issue := GetActionIssue(ctx) + if ctx.Written() { + return + } + + if ctx.HasError() { + ctx.Handle(500, "ChangeIssueReaction", errors.New(ctx.GetErrMsg())) + return + } + + switch ctx.Params(":action") { + case "react": + reaction, err := models.CreateIssueReaction(ctx.User, issue, form.Content) + if err != nil { + log.Info("CreateIssueReaction: %s", err) + break + } + // Reload new reactions + issue.Reactions = nil + if err = issue.LoadAttributes(); err != nil { + log.Info("issue.LoadAttributes: %s", err) + break + } + + log.Trace("Reaction for issue created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, reaction.ID) + case "unreact": + if err := models.DeleteIssueReaction(ctx.User, issue, form.Content); err != nil { + ctx.Handle(500, "DeleteIssueReaction", err) + return + } + + // Reload new reactions + issue.Reactions = nil + if err := issue.LoadAttributes(); err != nil { + log.Info("issue.LoadAttributes: %s", err) + break + } + + log.Trace("Reaction for issue removed: %d/%d", ctx.Repo.Repository.ID, issue.ID) + default: + ctx.Handle(404, fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil) + return + } + + if len(issue.Reactions) == 0 { + ctx.JSON(200, map[string]interface{}{ + "empty": true, + "html": "", + }) + return + } + + html, err := ctx.HTMLString(string(tplReactions), map[string]interface{}{ + "ctx": ctx.Data, + "ActionURL": fmt.Sprintf("%s/issues/%d/reactions", ctx.Repo.RepoLink, issue.Index), + "Reactions": issue.Reactions.GroupByType(), + }) + if err != nil { + ctx.Handle(500, "ChangeIssueReaction.HTMLString", err) + return + } + ctx.JSON(200, map[string]interface{}{ + "html": html, + }) +} + +// ChangeCommentReaction create a reaction for comment +func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) { + comment, err := models.GetCommentByID(ctx.ParamsInt64(":id")) + if err != nil { + ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + return + } + + issue, err := models.GetIssueByID(comment.IssueID) + checkIssueRights(ctx, issue) + if ctx.Written() { + return + } + + if ctx.HasError() { + ctx.Handle(500, "ChangeCommentReaction", errors.New(ctx.GetErrMsg())) + return + } + + switch ctx.Params(":action") { + case "react": + reaction, err := models.CreateCommentReaction(ctx.User, issue, comment, form.Content) + if err != nil { + log.Info("CreateCommentReaction: %s", err) + break + } + // Reload new reactions + comment.Reactions = nil + if err = comment.LoadReactions(); err != nil { + log.Info("comment.LoadReactions: %s", err) + break + } + + log.Trace("Reaction for comment created: %d/%d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID, reaction.ID) + case "unreact": + if err := models.DeleteCommentReaction(ctx.User, issue, comment, form.Content); err != nil { + ctx.Handle(500, "DeleteCommentReaction", err) + return + } + + // Reload new reactions + comment.Reactions = nil + if err = comment.LoadReactions(); err != nil { + log.Info("comment.LoadReactions: %s", err) + break + } + + log.Trace("Reaction for comment removed: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID) + default: + ctx.Handle(404, fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil) + return + } + + if len(comment.Reactions) == 0 { + ctx.JSON(200, map[string]interface{}{ + "empty": true, + "html": "", + }) + return + } + + html, err := ctx.HTMLString(string(tplReactions), map[string]interface{}{ + "ctx": ctx.Data, + "ActionURL": fmt.Sprintf("%s/comments/%d/reactions", ctx.Repo.RepoLink, comment.ID), + "Reactions": comment.Reactions.GroupByType(), + }) + if err != nil { + ctx.Handle(500, "ChangeCommentReaction.HTMLString", err) + return + } + ctx.JSON(200, map[string]interface{}{ + "html": html, + }) +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 56d4b5393b..f4fb135629 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -495,6 +495,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/cancel", repo.CancelStopwatch) }) }) + m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction) }) m.Post("/labels", reqRepoWriter, repo.UpdateIssueLabel) @@ -505,6 +506,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/comments/:id", func() { m.Post("", repo.UpdateCommentContent) m.Post("/delete", repo.DeleteComment) + m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeCommentReaction) }, context.CheckAnyUnit(models.UnitTypeIssues, models.UnitTypePullRequests)) m.Group("/labels", func() { m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel) |