summaryrefslogtreecommitdiffstats
path: root/routers/repo/issue.go
diff options
context:
space:
mode:
Diffstat (limited to 'routers/repo/issue.go')
-rw-r--r--routers/repo/issue.go157
1 files changed, 154 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,
+ })
+}