| @@ -409,7 +409,10 @@ issues.commented_at = `commented at <a id="%[1]s" href="#%[1]s">%[2]s</a>` | |||
| issues.no_content = There is no content yet. | |||
| issues.close_issue = Close | |||
| issues.close_comment_issue = Close and comment | |||
| issues.reopen_issue = Reopen | |||
| issues.reopen_comment_issue = Reopen and comment | |||
| issues.create_comment = Comment | |||
| issues.closed_at = `closed at <a id="%[1]s" href="#%[1]s">%[2]s</a>` | |||
| issues.label_title = Label name | |||
| issues.label_color = Label color | |||
| issues.label_count = %d labels | |||
| @@ -153,7 +153,7 @@ func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string | |||
| url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1) | |||
| message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message) | |||
| if _, err = CreateComment(u, repo, issue, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil { | |||
| if _, err = CreateComment(u, repo, issue, 0, 0, COMMENT_TYPE_COMMIT_REF, message, nil); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| @@ -798,7 +798,7 @@ func GetLabelsByIssueID(issueID int64) ([]*Label, error) { | |||
| } | |||
| func updateLabel(e Engine, l *Label) error { | |||
| _, err := x.Id(l.ID).AllCols().Update(l) | |||
| _, err := e.Id(l.ID).AllCols().Update(l) | |||
| return err | |||
| } | |||
| @@ -1222,11 +1222,13 @@ const ( | |||
| COMMENT_TYPE_CLOSE | |||
| // References. | |||
| COMMENT_TYPE_ISSUE | |||
| // Reference from some commit (not part of a pull request) | |||
| COMMENT_TYPE_COMMIT | |||
| // Reference from some pull request | |||
| COMMENT_TYPE_PULL | |||
| COMMENT_TYPE_ISSUE_REF | |||
| // Reference from a commit (not part of a pull request) | |||
| COMMENT_TYPE_COMMIT_REF | |||
| // Reference from a comment | |||
| COMMENT_TYPE_COMMENT_REF | |||
| // Reference from a pull request | |||
| COMMENT_TYPE_PULL_REF | |||
| ) | |||
| // Comment represents a comment in commit and issue page. | |||
| @@ -1245,11 +1247,16 @@ type Comment struct { | |||
| Attachments []*Attachment `xorm:"-"` | |||
| } | |||
| // HashTag returns unique hash tag for issue. | |||
| // HashTag returns unique hash tag for comment. | |||
| func (c *Comment) HashTag() string { | |||
| return "issuecomment-" + com.ToStr(c.ID) | |||
| } | |||
| // EventTag returns unique event hash tag for comment. | |||
| func (c *Comment) EventTag() string { | |||
| return "event-" + com.ToStr(c.ID) | |||
| } | |||
| func (c *Comment) AfterSet(colName string, _ xorm.Cell) { | |||
| var err error | |||
| switch colName { | |||
| @@ -112,7 +112,7 @@ func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) bi | |||
| type CreateCommentForm struct { | |||
| Content string | |||
| NewStatus string `binding:"OmitEmpty;In(reopen,close)"` | |||
| Status string `binding:"OmitEmpty;In(reopen,close)"` | |||
| Attachments []string | |||
| } | |||
| @@ -203,6 +203,22 @@ function initRepository() { | |||
| }); | |||
| } | |||
| // Issues | |||
| if ($('.repository.view.issue').length > 0) { | |||
| var $status_btn = $('#status-button'); | |||
| $('#content').keyup(function () { | |||
| if ($(this).val().length == 0) { | |||
| $status_btn.text($status_btn.data('status')) | |||
| } else { | |||
| $status_btn.text($status_btn.data('status-and-comment')) | |||
| } | |||
| }); | |||
| $status_btn.click(function () { | |||
| $('#status').val($status_btn.data('status-val')); | |||
| $('#comment-form').submit(); | |||
| }) | |||
| } | |||
| // Pull request | |||
| if ($('.repository.compare.pull').length > 0) { | |||
| var $branch_dropdown = $('.choose.branch .dropdown') | |||
| @@ -74,6 +74,15 @@ img { | |||
| &.red { | |||
| color: #d95c5c!important; | |||
| } | |||
| &.grey { | |||
| color: #767676!important; | |||
| a { | |||
| color: #444!important; | |||
| &:hover { | |||
| color: #000!important; | |||
| } | |||
| } | |||
| } | |||
| &.right { | |||
| text-align: right; | |||
| } | |||
| @@ -163,6 +163,19 @@ | |||
| } | |||
| } | |||
| .comment-list { | |||
| &:before { | |||
| display: block; | |||
| content: ""; | |||
| position: absolute; | |||
| margin-top: 12px; | |||
| margin-bottom: 14px; | |||
| top: 0; | |||
| bottom: 0; | |||
| left: 96px; | |||
| width: 2px; | |||
| background-color: #f3f3f3; | |||
| z-index: -1; | |||
| } | |||
| .comment { | |||
| .avatar { | |||
| width: @comment-avatar-width; | |||
| @@ -181,13 +194,6 @@ | |||
| max-width: 78%; | |||
| padding-top: 10px; | |||
| padding-bottom: 10px; | |||
| color: #767676; | |||
| a { | |||
| color: #444; | |||
| &:hover { | |||
| color: #000; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .markdown { | |||
| @@ -219,6 +225,25 @@ | |||
| } | |||
| } | |||
| } | |||
| .event { | |||
| position: relative; | |||
| margin: 15px 0 15px 79px; | |||
| padding-left: 25px; | |||
| .octicon { | |||
| width: 30px; | |||
| float: left; | |||
| margin-left: -36px; | |||
| text-align: center; | |||
| &.octicon-circle-slash { | |||
| font-size: 30px; | |||
| color: #bd2c00; | |||
| } | |||
| &.octicon-primitive-dot { | |||
| font-size: 35px; | |||
| color: #6cc644; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .ui.segment.metas { | |||
| margin-top: -3px; | |||
| @@ -720,9 +720,9 @@ func NewComment(ctx *middleware.Context, form auth.CreateCommentForm) { | |||
| // Check if issue owner/poster changes the status of issue. | |||
| if (ctx.Repo.IsOwner() || issue.IsPoster(ctx.User.Id)) && | |||
| (form.NewStatus == "reopen" || form.NewStatus == "close") { | |||
| (form.Status == "reopen" || form.Status == "close") { | |||
| issue.Repo = ctx.Repo.Repository | |||
| if err = issue.ChangeStatus(ctx.User, form.NewStatus == "close"); err != nil { | |||
| if err = issue.ChangeStatus(ctx.User, form.Status == "close"); err != nil { | |||
| ctx.Handle(500, "ChangeStatus", err) | |||
| return | |||
| } | |||
| @@ -4,7 +4,7 @@ | |||
| <a class="item" data-tab="preview" data-url="/api/v1/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "repo.release.preview"}}</a> | |||
| </div> | |||
| <div class="ui bottom attached active tab segment" data-tab="write"> | |||
| <textarea name="content"></textarea> | |||
| <textarea id="content" name="content"></textarea> | |||
| </div> | |||
| <div class="ui bottom attached tab segment markdown" data-tab="preview"> | |||
| {{.i18n.Tr "repo.release.loading"}} | |||
| @@ -27,7 +27,7 @@ | |||
| </a> | |||
| <div class="content"> | |||
| <div class="ui top attached header"> | |||
| <span class="text"><a href="{{.Issue.Poster.HomeLink}}">{{.Issue.Poster.Name}}</a> {{.i18n.Tr "repo.issues.commented_at" .Issue.HashTag $createdStr | Safe}}</span> | |||
| <span class="text grey"><a href="{{.Issue.Poster.HomeLink}}">{{.Issue.Poster.Name}}</a> {{.i18n.Tr "repo.issues.commented_at" .Issue.HashTag $createdStr | Safe}}</span> | |||
| <div class="ui right actions"> | |||
| </div> | |||
| </div> | |||
| @@ -52,13 +52,16 @@ | |||
| {{range .Issue.Comments}} | |||
| {{ $createdStr:= TimeSince .Created $.Lang }} | |||
| <!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF, 5 = COMMENT_REF, 6 = PULL_REF --> | |||
| {{if eq .Type 0}} | |||
| <div class="comment"> | |||
| <a class="avatar" href="{{.Poster.HomeLink}}"> | |||
| <img src="{{.Poster.AvatarLink}}"> | |||
| </a> | |||
| <div class="content"> | |||
| <div class="ui top attached header"> | |||
| <span class="text"><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> | |||
| </div> | |||
| @@ -80,6 +83,24 @@ | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| {{else if eq .Type 1}} | |||
| <div class="event"> | |||
| <span class="octicon octicon-primitive-dot"></span> | |||
| <a class="ui avatar image" href="{{.Poster.HomeLink}}"> | |||
| <img src="{{.Poster.AvatarLink}}"> | |||
| </a> | |||
| <span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a> {{$.i18n.Tr "repo.issues.closed_at" .EventTag $createdStr | Safe}}</span> | |||
| </div> | |||
| {{else if eq .Type 2}} | |||
| <div class="event"> | |||
| <span class="octicon octicon-circle-slash"></span> | |||
| <a class="ui avatar image" href="{{.Poster.HomeLink}}"> | |||
| <img src="{{.Poster.AvatarLink}}"> | |||
| </a> | |||
| <span class="text grey"><a href="{{.Poster.HomeLink}}">{{.Poster.Name}}</a> {{$.i18n.Tr "repo.issues.closed_at" .EventTag $createdStr | Safe}}</span> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| <div class="comment form"> | |||
| @@ -87,13 +108,20 @@ | |||
| <img src="{{.SignedUser.AvatarLink}}"> | |||
| </a> | |||
| <div class="content"> | |||
| <form class="ui segment form" action="{{.Link}}/comments" method="post"> | |||
| <form class="ui segment form" id="comment-form" action="{{.Link}}/comments" method="post"> | |||
| {{template "repo/issue/comment_tab" .}} | |||
| {{.CsrfTokenHtml}} | |||
| <input id="status" name="status" type="hidden"> | |||
| <div class="text right"> | |||
| <div class="ui red basic button" data-close="{{.i18n.Tr "repo.issues.close_issue"}}" data-close-and-comment="{{.i18n.Tr "repo.issues.close_comment_issue"}}"> | |||
| {{if .Issue.IsClosed}} | |||
| <div id="status-button" class="ui green basic button" data-status="{{.i18n.Tr "repo.issues.reopen_issue"}}" data-status-and-comment="{{.i18n.Tr "repo.issues.reopen_comment_issue"}}" data-status-val="reopen"> | |||
| {{.i18n.Tr "repo.issues.reopen_issue"}} | |||
| </div> | |||
| {{else}} | |||
| <div id="status-button" class="ui red basic button" data-status="{{.i18n.Tr "repo.issues.close_issue"}}" data-status-and-comment="{{.i18n.Tr "repo.issues.close_comment_issue"}}" data-status-val="close"> | |||
| {{.i18n.Tr "repo.issues.close_issue"}} | |||
| </div> | |||
| {{end}} | |||
| <button class="ui green button"> | |||
| {{.i18n.Tr "repo.issues.create_comment"}} | |||
| </button> | |||