Implement "conversation lock" for issue comments (#5073)
	
		
	
				
					
				
			
							parent
							
								
									64ce159a6e
								
							
						
					
					
						commit
						44114b38e6
					
				@ -0,0 +1,51 @@ | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package models | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IssueLockOptions defines options for locking and/or unlocking an issue/PR
 | 
				
			||||||
 | 
					type IssueLockOptions struct { | 
				
			||||||
 | 
						Doer   *User | 
				
			||||||
 | 
						Issue  *Issue | 
				
			||||||
 | 
						Reason string | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LockIssue locks an issue. This would limit commenting abilities to
 | 
				
			||||||
 | 
					// users with write access to the repo
 | 
				
			||||||
 | 
					func LockIssue(opts *IssueLockOptions) error { | 
				
			||||||
 | 
						return updateIssueLock(opts, true) | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnlockIssue unlocks a previously locked issue.
 | 
				
			||||||
 | 
					func UnlockIssue(opts *IssueLockOptions) error { | 
				
			||||||
 | 
						return updateIssueLock(opts, false) | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func updateIssueLock(opts *IssueLockOptions, lock bool) error { | 
				
			||||||
 | 
						if opts.Issue.IsLocked == lock { | 
				
			||||||
 | 
							return nil | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.Issue.IsLocked = lock | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var commentType CommentType | 
				
			||||||
 | 
						if opts.Issue.IsLocked { | 
				
			||||||
 | 
							commentType = CommentTypeLock | 
				
			||||||
 | 
						} else { | 
				
			||||||
 | 
							commentType = CommentTypeUnlock | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := UpdateIssueCols(opts.Issue, "is_locked"); err != nil { | 
				
			||||||
 | 
							return err | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := CreateComment(&CreateCommentOptions{ | 
				
			||||||
 | 
							Doer:    opts.Doer, | 
				
			||||||
 | 
							Issue:   opts.Issue, | 
				
			||||||
 | 
							Repo:    opts.Issue.Repo, | 
				
			||||||
 | 
							Type:    commentType, | 
				
			||||||
 | 
							Content: opts.Reason, | 
				
			||||||
 | 
						}) | 
				
			||||||
 | 
						return err | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,18 @@ | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package migrations | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/go-xorm/xorm" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func addIsLockedToIssues(x *xorm.Engine) error { | 
				
			||||||
 | 
						// Issue see models/issue.go
 | 
				
			||||||
 | 
						type Issue struct { | 
				
			||||||
 | 
							ID       int64 `xorm:"pk autoincr"` | 
				
			||||||
 | 
							IsLocked bool  `xorm:"NOT NULL DEFAULT false"` | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return x.Sync2(new(Issue)) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,71 @@ | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package repo | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ( | 
				
			||||||
 | 
						"net/http" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models" | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/auth" | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/context" | 
				
			||||||
 | 
					) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LockIssue locks an issue. This would limit commenting abilities to
 | 
				
			||||||
 | 
					// users with write access to the repo.
 | 
				
			||||||
 | 
					func LockIssue(ctx *context.Context, form auth.IssueLockForm) { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						issue := GetActionIssue(ctx) | 
				
			||||||
 | 
						if ctx.Written() { | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if issue.IsLocked { | 
				
			||||||
 | 
							ctx.Flash.Error(ctx.Tr("repo.issues.lock_duplicate")) | 
				
			||||||
 | 
							ctx.Redirect(issue.HTMLURL()) | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !form.HasValidReason() { | 
				
			||||||
 | 
							ctx.Flash.Error(ctx.Tr("repo.issues.lock.unknown_reason")) | 
				
			||||||
 | 
							ctx.Redirect(issue.HTMLURL()) | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := models.LockIssue(&models.IssueLockOptions{ | 
				
			||||||
 | 
							Doer:   ctx.User, | 
				
			||||||
 | 
							Issue:  issue, | 
				
			||||||
 | 
							Reason: form.Reason, | 
				
			||||||
 | 
						}); err != nil { | 
				
			||||||
 | 
							ctx.ServerError("LockIssue", err) | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther) | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnlockIssue unlocks a previously locked issue.
 | 
				
			||||||
 | 
					func UnlockIssue(ctx *context.Context) { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						issue := GetActionIssue(ctx) | 
				
			||||||
 | 
						if ctx.Written() { | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !issue.IsLocked { | 
				
			||||||
 | 
							ctx.Flash.Error(ctx.Tr("repo.issues.unlock_error")) | 
				
			||||||
 | 
							ctx.Redirect(issue.HTMLURL()) | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := models.UnlockIssue(&models.IssueLockOptions{ | 
				
			||||||
 | 
							Doer:  ctx.User, | 
				
			||||||
 | 
							Issue: issue, | 
				
			||||||
 | 
						}); err != nil { | 
				
			||||||
 | 
							ctx.ServerError("UnlockIssue", err) | 
				
			||||||
 | 
							return | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther) | 
				
			||||||
 | 
					} | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue