mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 03:25:11 +01:00 
			
		
		
		
	Refactor commentTags functionality (#17558)
* feat: Allow multiple tags on comments
- Allow for multiples tags(Currently Poster + {Owner, Writer}).
- Utilize the Poster tag within the commentTag function and remove the
checking from templates.
- Use bitwise on CommentTags to enable specific tags.
- Don't show poster tag(view_content.tmpl) on the initial issue comment.
* Change parameters naming
* Change function name
* refactor variable wording
* Merge 'master' branch into 'tags-comments' branch
* Change naming
* `tag` -> `role`
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									a4dc0c5a82
								
							
						
					
					
						commit
						492e1c2fbd
					
				| @ -71,7 +71,7 @@ type Issue struct { | ||||
| 	IsLocked bool `xorm:"NOT NULL DEFAULT false"` | ||||
| 
 | ||||
| 	// For view issue page. | ||||
| 	ShowTag CommentTag `xorm:"-"` | ||||
| 	ShowRole RoleDescriptor `xorm:"-"` | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
|  | ||||
| @ -105,17 +105,43 @@ const ( | ||||
| 	CommentTypeDismissReview | ||||
| ) | ||||
| 
 | ||||
| // CommentTag defines comment tag type | ||||
| type CommentTag int | ||||
| // RoleDescriptor defines comment tag type | ||||
| type RoleDescriptor int | ||||
| 
 | ||||
| // Enumerate all the comment tag types | ||||
| // Enumerate all the role tags. | ||||
| const ( | ||||
| 	CommentTagNone CommentTag = iota | ||||
| 	CommentTagPoster | ||||
| 	CommentTagWriter | ||||
| 	CommentTagOwner | ||||
| 	RoleDescriptorNone RoleDescriptor = iota | ||||
| 	RoleDescriptorPoster | ||||
| 	RoleDescriptorWriter | ||||
| 	RoleDescriptorOwner | ||||
| ) | ||||
| 
 | ||||
| // WithRole enable a specific tag on the RoleDescriptor. | ||||
| func (rd RoleDescriptor) WithRole(role RoleDescriptor) RoleDescriptor { | ||||
| 	rd |= (1 << role) | ||||
| 	return rd | ||||
| } | ||||
| 
 | ||||
| func stringToRoleDescriptor(role string) RoleDescriptor { | ||||
| 	switch role { | ||||
| 	case "Poster": | ||||
| 		return RoleDescriptorPoster | ||||
| 	case "Writer": | ||||
| 		return RoleDescriptorWriter | ||||
| 	case "Owner": | ||||
| 		return RoleDescriptorOwner | ||||
| 	default: | ||||
| 		return RoleDescriptorNone | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // HasRole returns if a certain role is enabled on the RoleDescriptor. | ||||
| func (rd RoleDescriptor) HasRole(role string) bool { | ||||
| 	roleDescriptor := stringToRoleDescriptor(role) | ||||
| 	bitValue := rd & (1 << roleDescriptor) | ||||
| 	return (bitValue > 0) | ||||
| } | ||||
| 
 | ||||
| // Comment represents a comment in commit and issue page. | ||||
| type Comment struct { | ||||
| 	ID               int64       `xorm:"pk autoincr"` | ||||
| @ -174,7 +200,7 @@ type Comment struct { | ||||
| 	Reactions   ReactionList  `xorm:"-"` | ||||
| 
 | ||||
| 	// For view issue page. | ||||
| 	ShowTag CommentTag `xorm:"-"` | ||||
| 	ShowRole RoleDescriptor `xorm:"-"` | ||||
| 
 | ||||
| 	Review      *Review `xorm:"-"` | ||||
| 	ReviewID    int64   `xorm:"index"` | ||||
|  | ||||
| @ -1015,38 +1015,46 @@ func NewIssuePost(ctx *context.Context) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // commentTag returns the CommentTag for a comment in/with the given repo, poster and issue | ||||
| func commentTag(repo *models.Repository, poster *models.User, issue *models.Issue) (models.CommentTag, error) { | ||||
| // roleDescriptor returns the Role Decriptor for a comment in/with the given repo, poster and issue | ||||
| func roleDescriptor(repo *models.Repository, poster *models.User, issue *models.Issue) (models.RoleDescriptor, error) { | ||||
| 	perm, err := models.GetUserRepoPermission(repo, poster) | ||||
| 	if err != nil { | ||||
| 		return models.CommentTagNone, err | ||||
| 		return models.RoleDescriptorNone, err | ||||
| 	} | ||||
| 
 | ||||
| 	// By default the poster has no roles on the comment. | ||||
| 	roleDescriptor := models.RoleDescriptorNone | ||||
| 
 | ||||
| 	// Check if the poster is owner of the repo. | ||||
| 	if perm.IsOwner() { | ||||
| 		// If the poster isn't a admin, enable the owner role. | ||||
| 		if !poster.IsAdmin { | ||||
| 			return models.CommentTagOwner, nil | ||||
| 		} | ||||
| 			roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorOwner) | ||||
| 		} else { | ||||
| 
 | ||||
| 		ok, err := models.IsUserRealRepoAdmin(repo, poster) | ||||
| 		if err != nil { | ||||
| 			return models.CommentTagNone, err | ||||
| 			// Otherwise check if poster is the real repo admin. | ||||
| 			ok, err := models.IsUserRealRepoAdmin(repo, poster) | ||||
| 			if err != nil { | ||||
| 				return models.RoleDescriptorNone, err | ||||
| 			} | ||||
| 			if ok { | ||||
| 				roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorOwner) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if ok { | ||||
| 			return models.CommentTagOwner, nil | ||||
| 		} | ||||
| 
 | ||||
| 		if ok, err = repo.IsCollaborator(poster.ID); ok && err == nil { | ||||
| 			return models.CommentTagWriter, nil | ||||
| 		} | ||||
| 
 | ||||
| 		return models.CommentTagNone, err | ||||
| 	} | ||||
| 
 | ||||
| 	if perm.CanWriteIssuesOrPulls(issue.IsPull) { | ||||
| 		return models.CommentTagWriter, nil | ||||
| 	// Is the poster can write issues or pulls to the repo, enable the Writer role. | ||||
| 	// Only enable this if the poster doesn't have the owner role already. | ||||
| 	if !roleDescriptor.HasRole("Owner") && perm.CanWriteIssuesOrPulls(issue.IsPull) { | ||||
| 		roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorWriter) | ||||
| 	} | ||||
| 
 | ||||
| 	return models.CommentTagNone, nil | ||||
| 	// If the poster is the actual poster of the issue, enable Poster role. | ||||
| 	if issue.IsPoster(poster.ID) { | ||||
| 		roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorPoster) | ||||
| 	} | ||||
| 
 | ||||
| 	return roleDescriptor, nil | ||||
| } | ||||
| 
 | ||||
| func getBranchData(ctx *context.Context, issue *models.Issue) { | ||||
| @ -1249,9 +1257,9 @@ func ViewIssue(ctx *context.Context) { | ||||
| 	} | ||||
| 
 | ||||
| 	var ( | ||||
| 		tag          models.CommentTag | ||||
| 		role         models.RoleDescriptor | ||||
| 		ok           bool | ||||
| 		marked       = make(map[int64]models.CommentTag) | ||||
| 		marked       = make(map[int64]models.RoleDescriptor) | ||||
| 		comment      *models.Comment | ||||
| 		participants = make([]*models.User, 1, 10) | ||||
| 	) | ||||
| @ -1298,11 +1306,11 @@ func ViewIssue(ctx *context.Context) { | ||||
| 	// check if dependencies can be created across repositories | ||||
| 	ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies | ||||
| 
 | ||||
| 	if issue.ShowTag, err = commentTag(repo, issue.Poster, issue); err != nil { | ||||
| 		ctx.ServerError("commentTag", err) | ||||
| 	if issue.ShowRole, err = roleDescriptor(repo, issue.Poster, issue); err != nil { | ||||
| 		ctx.ServerError("roleDescriptor", err) | ||||
| 		return | ||||
| 	} | ||||
| 	marked[issue.PosterID] = issue.ShowTag | ||||
| 	marked[issue.PosterID] = issue.ShowRole | ||||
| 
 | ||||
| 	// Render comments and and fetch participants. | ||||
| 	participants[0] = issue.Poster | ||||
| @ -1331,18 +1339,18 @@ func ViewIssue(ctx *context.Context) { | ||||
| 				return | ||||
| 			} | ||||
| 			// Check tag. | ||||
| 			tag, ok = marked[comment.PosterID] | ||||
| 			role, ok = marked[comment.PosterID] | ||||
| 			if ok { | ||||
| 				comment.ShowTag = tag | ||||
| 				comment.ShowRole = role | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			comment.ShowTag, err = commentTag(repo, comment.Poster, issue) | ||||
| 			comment.ShowRole, err = roleDescriptor(repo, comment.Poster, issue) | ||||
| 			if err != nil { | ||||
| 				ctx.ServerError("commentTag", err) | ||||
| 				ctx.ServerError("roleDescriptor", err) | ||||
| 				return | ||||
| 			} | ||||
| 			marked[comment.PosterID] = comment.ShowTag | ||||
| 			marked[comment.PosterID] = comment.ShowRole | ||||
| 			participants = addParticipant(comment.Poster, participants) | ||||
| 		} else if comment.Type == models.CommentTypeLabel { | ||||
| 			if err = comment.LoadLabel(); err != nil { | ||||
| @ -1430,18 +1438,18 @@ func ViewIssue(ctx *context.Context) { | ||||
| 				for _, lineComments := range codeComments { | ||||
| 					for _, c := range lineComments { | ||||
| 						// Check tag. | ||||
| 						tag, ok = marked[c.PosterID] | ||||
| 						role, ok = marked[c.PosterID] | ||||
| 						if ok { | ||||
| 							c.ShowTag = tag | ||||
| 							c.ShowRole = role | ||||
| 							continue | ||||
| 						} | ||||
| 
 | ||||
| 						c.ShowTag, err = commentTag(repo, c.Poster, issue) | ||||
| 						c.ShowRole, err = roleDescriptor(repo, c.Poster, issue) | ||||
| 						if err != nil { | ||||
| 							ctx.ServerError("commentTag", err) | ||||
| 							ctx.ServerError("roleDescriptor", err) | ||||
| 							return | ||||
| 						} | ||||
| 						marked[c.PosterID] = c.ShowTag | ||||
| 						marked[c.PosterID] = c.ShowRole | ||||
| 						participants = addParticipant(c.Poster, participants) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| @ -49,14 +49,17 @@ | ||||
| 						</div> | ||||
| 						<div class="comment-header-right actions df ac"> | ||||
| 							{{if not $.Repository.IsArchived}} | ||||
| 								{{if gt .Issue.ShowTag 0}} | ||||
| 									<div class="ui basic label"> | ||||
| 										{{if eq .Issue.ShowTag 2}} | ||||
| 								{{if gt .Issue.ShowRole 0}} | ||||
| 									{{if (.Issue.ShowRole.HasRole "Writer")}} | ||||
| 										<div class="ui basic label"> | ||||
| 											{{$.i18n.Tr "repo.issues.collaborator"}} | ||||
| 										{{else if eq .Issue.ShowTag 3}} | ||||
| 										</div> | ||||
| 									{{end}} | ||||
| 									{{if (.Issue.ShowRole.HasRole "Owner")}} | ||||
| 										<div class="ui basic label"> | ||||
| 											{{$.i18n.Tr "repo.issues.owner"}} | ||||
| 										{{end}} | ||||
| 									</div> | ||||
| 										</div> | ||||
| 									{{end}} | ||||
| 								{{end}} | ||||
| 								{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}} | ||||
| 								{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}} | ||||
|  | ||||
| @ -44,18 +44,19 @@ | ||||
| 					</div> | ||||
| 					<div class="comment-header-right actions df ac"> | ||||
| 						{{if not $.Repository.IsArchived}} | ||||
| 							{{if or (and (eq .PosterID .Issue.PosterID) (eq .Issue.OriginalAuthorID 0)) (and (eq .Issue.OriginalAuthorID .OriginalAuthorID) (not (eq .OriginalAuthorID 0))) }} | ||||
| 							{{if (.ShowRole.HasRole "Poster")}} | ||||
| 								<div class="ui basic label"> | ||||
| 									{{$.i18n.Tr "repo.issues.poster"}} | ||||
| 								</div> | ||||
| 							{{end}} | ||||
| 							{{if gt .ShowTag 0}} | ||||
| 							{{if (.ShowRole.HasRole "Writer")}} | ||||
| 								<div class="ui basic label"> | ||||
| 									{{if eq .ShowTag 2}} | ||||
| 										{{$.i18n.Tr "repo.issues.collaborator"}} | ||||
| 									{{else if eq .ShowTag 3}} | ||||
| 										{{$.i18n.Tr "repo.issues.owner"}} | ||||
| 									{{end}} | ||||
| 									{{$.i18n.Tr "repo.issues.collaborator"}} | ||||
| 								</div> | ||||
| 							{{end}} | ||||
| 							{{if (.ShowRole.HasRole "Owner")}} | ||||
| 								<div class="ui basic label"> | ||||
| 									{{$.i18n.Tr "repo.issues.owner"}} | ||||
| 								</div> | ||||
| 							{{end}} | ||||
| 							{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | ||||
| @ -549,24 +550,23 @@ | ||||
| 															</span> | ||||
| 														</div> | ||||
| 														<div class="comment-header-right actions df ac"> | ||||
| 															{{if not $.Repository.IsArchived}} | ||||
| 																{{if or (and (eq .PosterID $.Issue.PosterID) (eq $.Issue.OriginalAuthorID 0)) (eq $.Issue.OriginalAuthorID .OriginalAuthorID) }} | ||||
| 																	<div class="ui basic label"> | ||||
| 																		{{$.i18n.Tr "repo.issues.poster"}} | ||||
| 																	</div> | ||||
| 																{{end}} | ||||
| 																{{if gt .ShowTag 0}} | ||||
| 																	<div class="ui basic label"> | ||||
| 																		{{if eq .ShowTag 2}} | ||||
| 																			{{$.i18n.Tr "repo.issues.collaborator"}} | ||||
| 																		{{else if eq .ShowTag 3}} | ||||
| 																			{{$.i18n.Tr "repo.issues.owner"}} | ||||
| 																		{{end}} | ||||
| 																	</div> | ||||
| 																{{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))}} | ||||
| 															{{if (.ShowRole.HasRole "Poster")}} | ||||
| 																<div class="ui basic label"> | ||||
| 																	{{$.i18n.Tr "repo.issues.poster"}} | ||||
| 																</div> | ||||
| 															{{end}} | ||||
| 															{{if (.ShowRole.HasRole "Writer")}} | ||||
| 																<div class="ui basic label"> | ||||
| 																	{{$.i18n.Tr "repo.issues.collaborator"}} | ||||
| 																</div> | ||||
| 															{{end}} | ||||
| 															{{if (.ShowRole.HasRole "Owner")}} | ||||
| 																<div class="ui basic label"> | ||||
| 																	{{$.i18n.Tr "repo.issues.owner"}} | ||||
| 																</div> | ||||
| 															{{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))}} | ||||
| 														</div> | ||||
| 													</div> | ||||
| 													<div class="text comment-content"> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user