mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Show owner/poster tags of comments and fix #1312
This commit is contained in:
		| @@ -97,7 +97,6 @@ There are 5 ways to install Gogs: | |||||||
| - Mail Service, modules design is inspired by [WeTalk](https://github.com/beego/wetalk). | - Mail Service, modules design is inspired by [WeTalk](https://github.com/beego/wetalk). | ||||||
| - System Monitor Status is inspired by [GoBlog](https://github.com/fuxiaohei/goblog). | - System Monitor Status is inspired by [GoBlog](https://github.com/fuxiaohei/goblog). | ||||||
| - Thanks [lavachen](http://www.lavachen.cn/) and [Rocker](http://weibo.com/rocker1989) for designing Logo. | - Thanks [lavachen](http://www.lavachen.cn/) and [Rocker](http://weibo.com/rocker1989) for designing Logo. | ||||||
| - Thanks [gobuild.io](http://gobuild.io) for providing binary compile and download service. |  | ||||||
| - Thanks [Crowdin](https://crowdin.com/project/gogs) for providing open source translation plan. | - Thanks [Crowdin](https://crowdin.com/project/gogs) for providing open source translation plan. | ||||||
|  |  | ||||||
| ## Contributors | ## Contributors | ||||||
|   | |||||||
| @@ -67,7 +67,6 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自 | |||||||
| - 基于 [Macaron](https://github.com/Unknwon/macaron) 的路由与中间件机制。 | - 基于 [Macaron](https://github.com/Unknwon/macaron) 的路由与中间件机制。 | ||||||
| - 基于 [WeTalk](https://github.com/beego/wetalk) 修改的邮件服务和模块设计。 | - 基于 [WeTalk](https://github.com/beego/wetalk) 修改的邮件服务和模块设计。 | ||||||
| - 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。 | - 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。 | ||||||
| - 感谢 [gobuild.io](http://gobuild.io) 提供二进制编译与下载服务。 |  | ||||||
| - 感谢 [lavachen](http://www.lavachen.cn/) 和 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。 | - 感谢 [lavachen](http://www.lavachen.cn/) 和 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。 | ||||||
| - 感谢 [Crowdin](https://crowdin.com/project/gogs) 提供免费的开源项目本地化支持。 | - 感谢 [Crowdin](https://crowdin.com/project/gogs) 提供免费的开源项目本地化支持。 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -413,6 +413,13 @@ issues.reopen_issue = Reopen | |||||||
| issues.reopen_comment_issue = Reopen and comment | issues.reopen_comment_issue = Reopen and comment | ||||||
| issues.create_comment = Comment | issues.create_comment = Comment | ||||||
| issues.closed_at = `closed at <a id="%[1]s" href="#%[1]s">%[2]s</a>` | issues.closed_at = `closed at <a id="%[1]s" href="#%[1]s">%[2]s</a>` | ||||||
|  | issues.reopened_at = `reopened at <a id="%[1]s" href="#%[1]s">%[2]s</a>` | ||||||
|  | issues.poster = Poster | ||||||
|  | issues.admin = Admin | ||||||
|  | issues.owner = Owner | ||||||
|  | issues.not_signed_in = You must sign in to comment | ||||||
|  | issues.sign_up_for_free = Sign up for free | ||||||
|  | issues.sign_in_require_desc = to join this conversation. Already have an account? <a href="%s">Sign in to comment</a> | ||||||
| issues.label_title = Label name | issues.label_title = Label name | ||||||
| issues.label_color = Label color | issues.label_color = Label color | ||||||
| issues.label_count = %d labels | issues.label_count = %d labels | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const APP_VER = "0.6.4.0813 Beta" | const APP_VER = "0.6.4.0814 Beta" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|   | |||||||
| @@ -1231,6 +1231,15 @@ const ( | |||||||
| 	COMMENT_TYPE_PULL_REF | 	COMMENT_TYPE_PULL_REF | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | type CommentTag int | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	COMMENT_TAG_NONE CommentTag = iota | ||||||
|  | 	COMMENT_TAG_POSTER | ||||||
|  | 	COMMENT_TAG_ADMIN | ||||||
|  | 	COMMENT_TAG_OWNER | ||||||
|  | ) | ||||||
|  |  | ||||||
| // Comment represents a comment in commit and issue page. | // Comment represents a comment in commit and issue page. | ||||||
| type Comment struct { | type Comment struct { | ||||||
| 	ID              int64 `xorm:"pk autoincr"` | 	ID              int64 `xorm:"pk autoincr"` | ||||||
| @@ -1245,6 +1254,9 @@ type Comment struct { | |||||||
| 	Created         time.Time `xorm:"CREATED"` | 	Created         time.Time `xorm:"CREATED"` | ||||||
|  |  | ||||||
| 	Attachments []*Attachment `xorm:"-"` | 	Attachments []*Attachment `xorm:"-"` | ||||||
|  |  | ||||||
|  | 	// For view issue page. | ||||||
|  | 	ShowTag CommentTag `xorm:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // HashTag returns unique hash tag for comment. | // HashTag returns unique hash tag for comment. | ||||||
|   | |||||||
| @@ -247,8 +247,8 @@ func (repo *Repository) HasAccess(u *User) bool { | |||||||
| 	return has | 	return has | ||||||
| } | } | ||||||
|  |  | ||||||
| func (repo *Repository) IsOwnedBy(u *User) bool { | func (repo *Repository) IsOwnedBy(userID int64) bool { | ||||||
| 	return repo.OwnerID == u.Id | 	return repo.OwnerID == userID | ||||||
| } | } | ||||||
|  |  | ||||||
| // DescriptionHtml does special handles to description and return HTML string. | // DescriptionHtml does special handles to description and return HTML string. | ||||||
|   | |||||||
| @@ -222,6 +222,25 @@ func (u *User) UploadAvatar(data []byte) error { | |||||||
| 	return sess.Commit() | 	return sess.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // IsAdminOfRepo returns true if user has admin or higher access of repository. | ||||||
|  | func (u *User) IsAdminOfRepo(repo *Repository) bool { | ||||||
|  | 	if err := repo.GetOwner(); err != nil { | ||||||
|  | 		log.Error(3, "GetOwner: %v", err) | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if repo.Owner.IsOrganization() { | ||||||
|  | 		has, err := HasAccess(u, repo, ACCESS_MODE_ADMIN) | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Error(3, "HasAccess: %v", err) | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		return has | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return repo.IsOwnedBy(u.Id) | ||||||
|  | } | ||||||
|  |  | ||||||
| // IsOrganization returns true if user is actually a organization. | // IsOrganization returns true if user is actually a organization. | ||||||
| func (u *User) IsOrganization() bool { | func (u *User) IsOrganization() bool { | ||||||
| 	return u.Type == ORGANIZATION | 	return u.Type == ORGANIZATION | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -5,12 +5,16 @@ | |||||||
| package middleware | package middleware | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/macaron" | 	"github.com/Unknwon/macaron" | ||||||
| 	"github.com/macaron-contrib/csrf" | 	"github.com/macaron-contrib/csrf" | ||||||
|  |  | ||||||
|  | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/auth" | 	"github.com/gogits/gogs/modules/auth" | ||||||
|  | 	"github.com/gogits/gogs/modules/base" | ||||||
|  | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -21,6 +25,41 @@ type ToggleOptions struct { | |||||||
| 	DisableCsrf    bool | 	DisableCsrf    bool | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // AutoSignIn reads cookie and try to auto-login. | ||||||
|  | func AutoSignIn(ctx *Context) (bool, error) { | ||||||
|  | 	uname := ctx.GetCookie(setting.CookieUserName) | ||||||
|  | 	if len(uname) == 0 { | ||||||
|  | 		return false, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	isSucceed := false | ||||||
|  | 	defer func() { | ||||||
|  | 		if !isSucceed { | ||||||
|  | 			log.Trace("auto-login cookie cleared: %s", uname) | ||||||
|  | 			ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl) | ||||||
|  | 			ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl) | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	u, err := models.GetUserByName(uname) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if !models.IsErrUserNotExist(err) { | ||||||
|  | 			return false, fmt.Errorf("GetUserByName: %v", err) | ||||||
|  | 		} | ||||||
|  | 		return false, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if val, _ := ctx.GetSuperSecureCookie( | ||||||
|  | 		base.EncodeMd5(u.Rands+u.Passwd), setting.CookieRememberName); val != u.Name { | ||||||
|  | 		return false, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	isSucceed = true | ||||||
|  | 	ctx.Session.Set("uid", u.Id) | ||||||
|  | 	ctx.Session.Set("uname", u.Name) | ||||||
|  | 	return true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
| func Toggle(options *ToggleOptions) macaron.Handler { | func Toggle(options *ToggleOptions) macaron.Handler { | ||||||
| 	return func(ctx *Context) { | 	return func(ctx *Context) { | ||||||
| 		// Cannot view any page before installation. | 		// Cannot view any page before installation. | ||||||
|   | |||||||
| @@ -197,6 +197,14 @@ func Contexter() macaron.Handler { | |||||||
|  |  | ||||||
| 		ctx.Data["PageStartTime"] = time.Now() | 		ctx.Data["PageStartTime"] = time.Now() | ||||||
|  |  | ||||||
|  | 		// Check auto-signin. | ||||||
|  | 		if sess.Get("uid") == nil { | ||||||
|  | 			if _, err := AutoSignIn(ctx); err != nil { | ||||||
|  | 				ctx.Handle(500, "AutoSignIn", err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// Get user from session if logined. | 		// Get user from session if logined. | ||||||
| 		ctx.User, ctx.IsBasicAuth = auth.SignedInUser(ctx.Req.Request, ctx.Session) | 		ctx.User, ctx.IsBasicAuth = auth.SignedInUser(ctx.Req.Request, ctx.Session) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -180,6 +180,14 @@ | |||||||
| 				.avatar { | 				.avatar { | ||||||
| 					width: @comment-avatar-width; | 					width: @comment-avatar-width; | ||||||
| 				} | 				} | ||||||
|  | 				.tag {     | ||||||
|  | 					color: #767676; | ||||||
|  | 					margin-top: 3px; | ||||||
|  | 			    padding: 2px 5px; | ||||||
|  | 			    font-size: 12px; | ||||||
|  | 			    border: 1px solid rgba(0,0,0,0.1); | ||||||
|  | 			    border-radius: 3px; | ||||||
|  | 				} | ||||||
| 				.content { | 				.content { | ||||||
| 					margin-left: 4em; | 					margin-left: 4em; | ||||||
| 					.header { | 					.header { | ||||||
|   | |||||||
| @@ -427,7 +427,7 @@ func ViewIssue(ctx *middleware.Context) { | |||||||
| 	ctx.Data["Title"] = issue.Name | 	ctx.Data["Title"] = issue.Name | ||||||
|  |  | ||||||
| 	if err = issue.GetPoster(); err != nil { | 	if err = issue.GetPoster(); err != nil { | ||||||
| 		ctx.Handle(500, "GetPoster: %v", err) | 		ctx.Handle(500, "GetPoster", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink)) | 	issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink)) | ||||||
| @@ -441,7 +441,7 @@ func ViewIssue(ctx *middleware.Context) { | |||||||
| 	if ctx.IsSigned { | 	if ctx.IsSigned { | ||||||
| 		// Update issue-user. | 		// Update issue-user. | ||||||
| 		if err = issue.ReadBy(ctx.User.Id); err != nil { | 		if err = issue.ReadBy(ctx.User.Id); err != nil { | ||||||
| 			ctx.Handle(500, "ReadBy: %v", err) | 			ctx.Handle(500, "ReadBy", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -475,10 +475,35 @@ func ViewIssue(ctx *middleware.Context) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	var ( | ||||||
|  | 		repo    = ctx.Repo.Repository | ||||||
|  | 		tag     models.CommentTag | ||||||
|  | 		ok      bool | ||||||
|  | 		marked  = make(map[int64]models.CommentTag) | ||||||
|  | 		comment *models.Comment | ||||||
|  | 	) | ||||||
| 	// Render comments. | 	// Render comments. | ||||||
| 	for i := range issue.Comments { | 	for _, comment = range issue.Comments { | ||||||
| 		if issue.Comments[i].Type == models.COMMENT_TYPE_COMMENT { | 		if comment.Type == models.COMMENT_TYPE_COMMENT { | ||||||
| 			issue.Comments[i].RenderedContent = string(base.RenderMarkdown([]byte(issue.Comments[i].Content), ctx.Repo.RepoLink)) | 			comment.RenderedContent = string(base.RenderMarkdown([]byte(comment.Content), ctx.Repo.RepoLink)) | ||||||
|  |  | ||||||
|  | 			// Check tag. | ||||||
|  | 			tag, ok = marked[comment.PosterID] | ||||||
|  | 			if ok { | ||||||
|  | 				comment.ShowTag = tag | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if repo.IsOwnedBy(comment.PosterID) || | ||||||
|  | 				(repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(comment.PosterID)) { | ||||||
|  | 				comment.ShowTag = models.COMMENT_TAG_OWNER | ||||||
|  | 			} else if comment.Poster.IsAdminOfRepo(repo) { | ||||||
|  | 				comment.ShowTag = models.COMMENT_TAG_ADMIN | ||||||
|  | 			} else if comment.PosterID == issue.PosterID { | ||||||
|  | 				comment.ShowTag = models.COMMENT_TAG_POSTER | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			marked[comment.PosterID] = comment.ShowTag | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -42,49 +42,22 @@ func SignIn(ctx *middleware.Context) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Check auto-login. | 	// Check auto-login. | ||||||
| 	uname := ctx.GetCookie(setting.CookieUserName) | 	isSucceed, err := middleware.AutoSignIn(ctx) | ||||||
| 	if len(uname) == 0 { |  | ||||||
| 		ctx.HTML(200, SIGNIN) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	isSucceed := false |  | ||||||
| 	defer func() { |  | ||||||
| 		if !isSucceed { |  | ||||||
| 			log.Trace("auto-login cookie cleared: %s", uname) |  | ||||||
| 			ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl) |  | ||||||
| 			ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	u, err := models.GetUserByName(uname) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if !models.IsErrUserNotExist(err) { | 		ctx.Handle(500, "AutoSignIn", err) | ||||||
| 			ctx.Handle(500, "GetUserByName", err) | 		return | ||||||
| 		} else { | 	} | ||||||
| 			ctx.HTML(200, SIGNIN) |  | ||||||
|  | 	if isSucceed { | ||||||
|  | 		if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 { | ||||||
|  | 			ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl) | ||||||
|  | 			ctx.Redirect(redirectTo) | ||||||
| 		} | 		} | ||||||
|  | 		ctx.Redirect(setting.AppSubUrl + "/") | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if val, _ := ctx.GetSuperSecureCookie( | 	ctx.HTML(200, SIGNIN) | ||||||
| 		base.EncodeMd5(u.Rands+u.Passwd), setting.CookieRememberName); val != u.Name { |  | ||||||
| 		ctx.HTML(200, SIGNIN) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	isSucceed = true |  | ||||||
|  |  | ||||||
| 	ctx.Session.Set("uid", u.Id) |  | ||||||
| 	ctx.Session.Set("uname", u.Name) |  | ||||||
| 	if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 { |  | ||||||
| 		ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl) |  | ||||||
| 		ctx.Redirect(redirectTo) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ctx.Redirect(setting.AppSubUrl + "/") |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func SignInPost(ctx *middleware.Context, form auth.SignInForm) { | func SignInPost(ctx *middleware.Context, form auth.SignInForm) { | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| 0.6.4.0813 Beta | 0.6.4.0814 Beta | ||||||
| @@ -22,8 +22,8 @@ | |||||||
| 	<div class="twelve wide column comment-list"> | 	<div class="twelve wide column comment-list"> | ||||||
|   	<ui class="ui comments"> |   	<ui class="ui comments"> | ||||||
|   		<div class="comment"> |   		<div class="comment"> | ||||||
| 		    <a class="avatar" href="{{.SignedUser.HomeLink}}"> | 		    <a class="avatar" href="{{.Issue.Poster.HomeLink}}"> | ||||||
| 		      <img src="{{.SignedUser.AvatarLink}}"> | 		      <img src="{{.Issue.Poster.AvatarLink}}"> | ||||||
| 		    </a> | 		    </a> | ||||||
| 		    <div class="content"> | 		    <div class="content"> | ||||||
| 					<div class="ui top attached header"> | 					<div class="ui top attached header"> | ||||||
| @@ -63,6 +63,17 @@ | |||||||
| 					<div class="ui top attached header"> | 					<div class="ui top attached header"> | ||||||
| 						<span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a> {{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdStr | Safe}}</span> | 						<span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a> {{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdStr | Safe}}</span> | ||||||
| 					  <div class="ui right actions"> | 					  <div class="ui right actions"> | ||||||
|  | 					  	{{if gt .ShowTag 0}} | ||||||
|  | 					  	<div class="tag"> | ||||||
|  | 					  	{{if eq .ShowTag 1}} | ||||||
|  | 							{{$.i18n.Tr "repo.issues.poster"}} | ||||||
|  | 					  	{{else if eq .ShowTag 2}} | ||||||
|  | 							{{$.i18n.Tr "repo.issues.admin"}} | ||||||
|  | 					  	{{else if eq .ShowTag 3}} | ||||||
|  | 							{{$.i18n.Tr "repo.issues.owner"}} | ||||||
|  | 					  	{{end}} | ||||||
|  | 					  	</div> | ||||||
|  | 					  	{{end}} | ||||||
| 					  </div> | 					  </div> | ||||||
| 					</div> | 					</div> | ||||||
| 			    <div class="ui attached segment markdown"> | 			    <div class="ui attached segment markdown"> | ||||||
| @@ -89,7 +100,7 @@ | |||||||
|   			<a class="ui avatar image" href="{{.Poster.HomeLink}}"> |   			<a class="ui avatar image" href="{{.Poster.HomeLink}}"> | ||||||
|   			  <img src="{{.Poster.AvatarLink}}"> |   			  <img src="{{.Poster.AvatarLink}}"> | ||||||
|   			</a> |   			</a> | ||||||
|   			<span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a> {{$.i18n.Tr "repo.issues.closed_at" .EventTag $createdStr | Safe}}</span> |   			<span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a> {{$.i18n.Tr "repo.issues.reopened_at" .EventTag $createdStr | Safe}}</span> | ||||||
|   		</div> |   		</div> | ||||||
|   		{{else if eq .Type 2}} |   		{{else if eq .Type 2}} | ||||||
|   		<div class="event"> |   		<div class="event"> | ||||||
| @@ -103,6 +114,7 @@ | |||||||
|  |  | ||||||
|   		{{end}} |   		{{end}} | ||||||
|  |  | ||||||
|  | 			{{if .IsSigned}} | ||||||
| 		  <div class="comment form"> | 		  <div class="comment form"> | ||||||
| 		    <a class="avatar" href="{{.SignedUser.HomeLink}}"> | 		    <a class="avatar" href="{{.SignedUser.HomeLink}}"> | ||||||
| 		      <img src="{{.SignedUser.AvatarLink}}"> | 		      <img src="{{.SignedUser.AvatarLink}}"> | ||||||
| @@ -129,6 +141,12 @@ | |||||||
| 			    </form> | 			    </form> | ||||||
| 		    </div> | 		    </div> | ||||||
| 		  </div> | 		  </div> | ||||||
|  | 		  {{else}} | ||||||
|  | 		  <div class="ui warning message"> | ||||||
|  | 		    <a href="/user/sign_up" class="ui green button">{{.i18n.Tr "repo.issues.sign_up_for_free"}}</a> | ||||||
|  | 		    {{.i18n.Tr "repo.issues.sign_in_require_desc" "/user/login" | Safe}} | ||||||
|  | 		  </div> | ||||||
|  | 		  {{end}} | ||||||
|   	</ui> |   	</ui> | ||||||
| 	</div> | 	</div> | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user