diff --git a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala index 8fea200..3cbd887 100644 --- a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala +++ b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala @@ -1,6 +1,6 @@ package gitbucket.core.controller -import gitbucket.core.model.WebHook +import gitbucket.core.model.{CommitComment, CommitComments, IssueComment, WebHook} import gitbucket.core.plugin.PluginRegistry import gitbucket.core.pulls.html import gitbucket.core.service.CommitStatusService @@ -113,33 +113,89 @@ val name = repository.name getPullRequest(owner, name, issueId) map { case (issue, pullreq) => - using(Git.open(getRepositoryDir(owner, name))) { - git => - val (commits, diffs) = - getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo) - html.pullreq( - issue, - pullreq, - (commits.flatten - .map(commit => getCommitComments(owner, name, commit.id, true)) - .flatten - .toList ::: getComments(owner, name, issueId)) - .sortWith((a, b) => a.registeredDate before b.registeredDate), - getIssueLabels(owner, name, issueId), - getAssignableUserNames(owner, name), - getMilestonesWithIssueCount(owner, name), - getPriorities(owner, name), - getLabels(owner, name), - commits, - diffs, - isEditable(repository), - isManageable(repository), - hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount), - repository, - getRepository(pullreq.requestUserName, pullreq.requestRepositoryName), - flash.toMap.map(f => f._1 -> f._2.toString) - ) - } + val (commits, _) = + getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo) + + html.conversation( + issue, + pullreq, + commits.flatten, + getPullRequestComments(owner, name, issue.issueId, commits.flatten), + getIssueLabels(owner, name, issueId), + getAssignableUserNames(owner, name), + getMilestonesWithIssueCount(owner, name), + getPriorities(owner, name), + getLabels(owner, name), + isEditable(repository), + isManageable(repository), + hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount), + repository, + getRepository(pullreq.requestUserName, pullreq.requestRepositoryName), + flash.toMap.map(f => f._1 -> f._2.toString) + ) + +// html.pullreq( +// issue, +// pullreq, +// comments, +// getIssueLabels(owner, name, issueId), +// getAssignableUserNames(owner, name), +// getMilestonesWithIssueCount(owner, name), +// getPriorities(owner, name), +// getLabels(owner, name), +// commits, +// diffs, +// isEditable(repository), +// isManageable(repository), +// hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount), +// repository, +// getRepository(pullreq.requestUserName, pullreq.requestRepositoryName), +// flash.toMap.map(f => f._1 -> f._2.toString) +// ) + } + } getOrElse NotFound() + }) + + get("/:owner/:repository/pull/:id/commits")(referrersOnly { repository => + params("id").toIntOpt.flatMap { issueId => + val owner = repository.owner + val name = repository.name + getPullRequest(owner, name, issueId) map { + case (issue, pullreq) => + val (commits, _) = + getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo) + + html.commits( + issue, + pullreq, + commits, + getPullRequestComments(owner, name, issue.issueId, commits.flatten), + isManageable(repository), + repository + ) + } + } getOrElse NotFound() + }) + + get("/:owner/:repository/pull/:id/files")(referrersOnly { repository => + params("id").toIntOpt.flatMap { + issueId => + val owner = repository.owner + val name = repository.name + getPullRequest(owner, name, issueId) map { + case (issue, pullreq) => + val (commits, diffs) = + getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo) + + html.files( + issue, + pullreq, + diffs, + commits.flatten, + getPullRequestComments(owner, name, issue.issueId, commits.flatten), + isManageable(repository), + repository + ) } } getOrElse NotFound() }) diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index 3da3594..b3b7685 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -103,7 +103,8 @@ oldLineNumber: Option[Int], newLineNumber: Option[Int], content: String, - issueId: Option[Int] + issueId: Option[Int], + diff: Option[String] ) val uploadForm = mapping( @@ -138,7 +139,8 @@ "oldLineNumber" -> trim(label("Old line number", optional(number()))), "newLineNumber" -> trim(label("New line number", optional(number()))), "content" -> trim(label("Content", text(required))), - "issueId" -> trim(label("Issue Id", optional(number()))) + "issueId" -> trim(label("Issue Id", optional(number()))), + "diff" -> optional(text()) )(CommentForm.apply) /** @@ -562,6 +564,22 @@ form.newLineNumber, form.issueId ) + + for { + fileName <- form.fileName + diff <- form.diff + } { + saveCommitCommentDiff( + repository.owner, + repository.name, + id, + fileName, + form.oldLineNumber, + form.newLineNumber, + diff + ) + } + form.issueId match { case Some(issueId) => recordCommentPullRequestActivity( @@ -613,6 +631,22 @@ form.newLineNumber, form.issueId ) + + for { + fileName <- form.fileName + diff <- form.diff + } { + saveCommitCommentDiff( + repository.owner, + repository.name, + id, + fileName, + form.oldLineNumber, + form.newLineNumber, + diff + ) + } + val comment = getCommitComment(repository.owner, repository.name, commentId.toString).get form.issueId match { case Some(issueId) => diff --git a/src/main/scala/gitbucket/core/model/Comment.scala b/src/main/scala/gitbucket/core/model/Comment.scala index 8f79a52..8e5044c 100644 --- a/src/main/scala/gitbucket/core/model/Comment.scala +++ b/src/main/scala/gitbucket/core/model/Comment.scala @@ -1,6 +1,7 @@ package gitbucket.core.model +import java.util.Date -trait Comment { +sealed trait Comment { val commentedUserName: String val registeredDate: java.util.Date } @@ -87,3 +88,11 @@ updatedDate: java.util.Date, issueId: Option[Int] ) extends Comment + +case class CommitComments( + fileName: String, + commentedUserName: String, + registeredDate: Date, + comments: Seq[CommitComment], + diff: Option[String] +) extends Comment diff --git a/src/main/scala/gitbucket/core/service/CommitsService.scala b/src/main/scala/gitbucket/core/service/CommitsService.scala index c3142c7..237762d 100644 --- a/src/main/scala/gitbucket/core/service/CommitsService.scala +++ b/src/main/scala/gitbucket/core/service/CommitsService.scala @@ -1,9 +1,14 @@ package gitbucket.core.service +import java.io.File + import gitbucket.core.model.CommitComment import gitbucket.core.model.Profile._ import gitbucket.core.model.Profile.profile.blockingApi._ import gitbucket.core.model.Profile.dateColumnType +import gitbucket.core.util.Directory._ +import gitbucket.core.util.StringUtil +import org.apache.commons.io.FileUtils trait CommitsService { @@ -68,4 +73,48 @@ def deleteCommitComment(commentId: Int)(implicit s: Session) = CommitComments filter (_.byPrimaryKey(commentId)) delete + + def saveCommitCommentDiff( + owner: String, + repository: String, + commitId: String, + fileName: String, + oldLine: Option[Int], + newLine: Option[Int], + diffJson: String + ): Unit = { + val dir = new java.io.File(getDiffDir(owner, repository), commitId) + if (!dir.exists) { + dir.mkdirs() + } + val file = diffFile(dir, fileName, oldLine, newLine) + FileUtils.write(file, diffJson, "UTF-8") + } + + def loadCommitCommentDiff( + owner: String, + repository: String, + commitId: String, + fileName: String, + oldLine: Option[Int], + newLine: Option[Int] + ): Option[String] = { + val dir = new java.io.File(getDiffDir(owner, repository), commitId) + val file = diffFile(dir, fileName, oldLine, newLine) + if (file.exists) { + Option(FileUtils.readFileToString(file, "UTF-8")) + } else None + } + + private def diffFile(dir: java.io.File, fileName: String, oldLine: Option[Int], newLine: Option[Int]): File = { + new File( + dir, + StringUtil.sha1( + fileName + + "_oldLine:" + oldLine.map(_.toString).getOrElse("") + + "_newLine:" + newLine.map(_.toString).getOrElse("") + ) + ) + } + } diff --git a/src/main/scala/gitbucket/core/service/PullRequestService.scala b/src/main/scala/gitbucket/core/service/PullRequestService.scala index ddcb345..0f7f50c 100644 --- a/src/main/scala/gitbucket/core/service/PullRequestService.scala +++ b/src/main/scala/gitbucket/core/service/PullRequestService.scala @@ -1,6 +1,6 @@ package gitbucket.core.service -import gitbucket.core.model.{Issue, PullRequest, CommitStatus, CommitState, CommitComment} +import gitbucket.core.model.{CommitComments => _, Session => _, _} import gitbucket.core.model.Profile._ import gitbucket.core.model.Profile.profile.blockingApi._ import difflib.{Delta, DiffUtils} @@ -12,6 +12,7 @@ import gitbucket.core.view import gitbucket.core.view.helpers import org.eclipse.jgit.api.Git + import scala.collection.JavaConverters._ trait PullRequestService { self: IssuesService with CommitsService => @@ -314,11 +315,49 @@ helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime) } + // TODO Isolate to an another method? val diffs = JGitUtil.getDiffs(newGit, Some(oldId.getName), newId.getName, true, false) (commits, diffs) } + def getPullRequestComments(userName: String, repositoryName: String, issueId: Int, commits: Seq[CommitInfo])( + implicit s: Session + ): Seq[Comment] = { + (commits + .map(commit => getCommitComments(userName, repositoryName, commit.id, true)) + .flatten ++ getComments(userName, repositoryName, issueId)) + .groupBy { + case x: IssueComment => (Some(x.commentId), None, None, None) + case x: CommitComment if x.fileName.isEmpty => (Some(x.commentId), None, None, None) + case x: CommitComment => (None, x.fileName, x.oldLine, x.newLine) + case x => throw new MatchError(x) + } + .toSeq + .map { + // Normal comment + case ((Some(_), _, _, _), comments) => + comments.head + // Comment on a specific line of a commit + case ((None, Some(fileName), oldLine, newLine), comments) => + gitbucket.core.model.CommitComments( + fileName = fileName, + commentedUserName = comments.head.commentedUserName, + registeredDate = comments.head.registeredDate, + comments = comments.map(_.asInstanceOf[CommitComment]), + diff = loadCommitCommentDiff( + userName, + repositoryName, + comments.head.asInstanceOf[CommitComment].commitId, + fileName, + oldLine, + newLine + ) + ) + } + .sortWith(_.registeredDate before _.registeredDate) + } + } object PullRequestService { diff --git a/src/main/scala/gitbucket/core/util/Directory.scala b/src/main/scala/gitbucket/core/util/Directory.scala index 6e8a0b8..416b7a5 100644 --- a/src/main/scala/gitbucket/core/util/Directory.scala +++ b/src/main/scala/gitbucket/core/util/Directory.scala @@ -68,6 +68,12 @@ new File(getRepositoryFilesDir(owner, repository), "lfs") /** + * Directory for files which store diff fragment + */ + def getDiffDir(owner: String, repository: String): File = + new File(getRepositoryFilesDir(owner, repository), "diff") + + /** * Directory for uploaded files by the specified user. */ def getUserUploadDir(userName: String): File = diff --git a/src/main/scala/gitbucket/core/view/helpers.scala b/src/main/scala/gitbucket/core/view/helpers.scala index c5f1a40..848981a 100644 --- a/src/main/scala/gitbucket/core/view/helpers.scala +++ b/src/main/scala/gitbucket/core/view/helpers.scala @@ -3,6 +3,7 @@ import java.text.SimpleDateFormat import java.util.{Date, Locale, TimeZone} +import com.nimbusds.jose.util.JSONObjectUtils import gitbucket.core.controller.Context import gitbucket.core.model.CommitState import gitbucket.core.plugin.{PluginRegistry, RenderRequest} @@ -462,4 +463,44 @@ */ def readableSize(size: Option[Long]): String = FileUtil.readableSize(size.getOrElse(0)) + /** + * Make HTML fragment of the partial diff for a comment on a line of diff. + * + * @param jsonString JSON string which is stored in COMMIT_COMMENT table. + * @return HTML fragment of diff + */ + def diff(jsonString: String): Html = { + import org.json4s._ + import org.json4s.jackson.JsonMethods._ + implicit val formats = DefaultFormats + + val diff = parse(jsonString).extract[Seq[CommentDiffLine]] + + val sb = new StringBuilder() + sb.append("") + diff.foreach { line => + sb.append("") + sb.append(s"""") + sb.append(s"""") + + sb.append(s"""") + sb.append("") + } + sb.append("
""") + line.oldLine.foreach { oldLine => + sb.append(oldLine) + } + sb.append("""") + line.newLine.foreach { newLine => + sb.append(newLine) + } + sb.append("""") + sb.append(StringUtil.escapeHtml(line.text)) + sb.append("
") + + Html(sb.toString()) + } + + case class CommentDiffLine(newLine: Option[String], oldLine: Option[String], `type`: String, text: String) + } diff --git a/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html b/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html index cd242f2..15a57a6 100644 --- a/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html +++ b/src/main/twirl/gitbucket/core/helper/commitcomment.scala.html @@ -3,43 +3,34 @@ repository: gitbucket.core.service.RepositoryService.RepositoryInfo, latestCommitId: Option[String] = None)(implicit context: gitbucket.core.controller.Context) @import gitbucket.core.view.helpers -
-
-
- @helpers.avatar(comment.commentedUserName, 20) - @helpers.user(comment.commentedUserName, styleClass="username strong") - - commented on - @if(comment.issueId.isDefined){ - #@comment.issueId - } - @comment.fileName.map { fileName => - @fileName in - } - @comment.commitId.substring(0, 7) - @gitbucket.core.helper.html.datetimeago(comment.registeredDate) - - +
+
+
+
+ @helpers.avatar(comment.commentedUserName, 20) + @helpers.user(comment.commentedUserName, styleClass="username strong") + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) + @if(hasWritePermission || context.loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false)){   } - -
-
- @helpers.markdown( - markdown = comment.content, - repository = repository, - enableWikiLink = false, - enableRefsLink = true, - enableLineBreaks = true, - enableTaskList = false, - hasWritePermission = hasWritePermission - ) + +
+
+ @helpers.markdown( + markdown = comment.content, + repository = repository, + enableWikiLink = false, + enableRefsLink = true, + enableLineBreaks = true, + enableTaskList = false, + hasWritePermission = hasWritePermission + ) +
diff --git a/src/main/twirl/gitbucket/core/helper/commitcomments.scala.html b/src/main/twirl/gitbucket/core/helper/commitcomments.scala.html new file mode 100644 index 0000000..622a1c1 --- /dev/null +++ b/src/main/twirl/gitbucket/core/helper/commitcomments.scala.html @@ -0,0 +1,21 @@ +@(comments: gitbucket.core.model.CommitComments, + hasWritePermission: Boolean, + repository: gitbucket.core.service.RepositoryService.RepositoryInfo, + latestCommitId: Option[String] = None)(implicit context: gitbucket.core.controller.Context) +@import gitbucket.core.view.helpers +
+
+ @comments.fileName + @if(!latestCommitId.contains(comments.comments.head.commitId)) { + + } +
+
+ @comments.diff.map(helpers.diff) +
+ @comments.comments.map { comment => + @gitbucket.core.helper.html.commitcomment(comment, hasWritePermission, repository, latestCommitId) + } +
+
+
diff --git a/src/main/twirl/gitbucket/core/helper/diff.scala.html b/src/main/twirl/gitbucket/core/helper/diff.scala.html index c581c8b..ce58086 100644 --- a/src/main/twirl/gitbucket/core/helper/diff.scala.html +++ b/src/main/twirl/gitbucket/core/helper/diff.scala.html @@ -365,14 +365,14 @@ }); for(var key in elements){ filename = elements[key]['filename']; - oldline = elements[key]['oldline']; - newline = elements[key]['newline']; + oldline = elements[key]['oldline'] ? elements[key]['oldline'] : ''; + newline = elements[key]['newline'] ? elements[key]['newline'] : ''; var $v = $('
') - .append($('') - .data('filename', filename) - .data('newline', newline) - .data('oldline', oldline)); + .append($('')); var tmp; if (typeof oldline !== 'undefined') { diff --git a/src/main/twirl/gitbucket/core/issues/commentlist.scala.html b/src/main/twirl/gitbucket/core/issues/commentlist.scala.html index 43621f0..0fa4353 100644 --- a/src/main/twirl/gitbucket/core/issues/commentlist.scala.html +++ b/src/main/twirl/gitbucket/core/issues/commentlist.scala.html @@ -4,40 +4,39 @@ repository: gitbucket.core.service.RepositoryService.RepositoryInfo, pullreq: Option[gitbucket.core.model.PullRequest] = None)(implicit context: gitbucket.core.controller.Context) @import gitbucket.core.view.helpers -@import gitbucket.core.model.CommitComment @issueOrPullRequest()={ @if(issue.exists(_.isPullRequest))( "pull request" )else( "issue" ) } -@showFormatedComment(comment: gitbucket.core.model.IssueComment)={ +@showFormattedComment(comment: gitbucket.core.model.IssueComment)={
@helpers.avatar(comment.commentedUserName, 20) @helpers.user(comment.commentedUserName, styleClass="username strong") - @if(comment.action == "comment"){ - commented - } else { - referenced the @issueOrPullRequest() - } - - @gitbucket.core.helper.html.datetimeago(comment.registeredDate) - - + @if(comment.action == "comment"){ + commented + } else { + referenced the @issueOrPullRequest() + } + + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) + + @if(comment.action != "commit" && comment.action != "merge" && comment.action != "refer" && (isManageable || context.loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false))){ - -   - - + +   + + }
-
+
@helpers.markdown( - markdown = comment.content, - repository = repository, - enableWikiLink = false, - enableRefsLink = true, - enableLineBreaks = true, - enableTaskList = true, - hasWritePermission = isManageable + markdown = comment.content, + repository = repository, + enableWikiLink = false, + enableRefsLink = true, + enableLineBreaks = true, + enableTaskList = true, + hasWritePermission = isManageable )
@@ -54,7 +53,7 @@ }
-
+
@helpers.markdown( markdown = issue.get.content getOrElse "No description provided.", repository = repository, @@ -117,7 +116,7 @@
} case "merge" => { - @showFormatedComment(comment) + @showFormattedComment(comment)
@@ -136,7 +135,7 @@ } case "close" | "close_comment" => { @if(comment.action == "close_comment"){ - @showFormatedComment(comment) + @showFormattedComment(comment) }
@@ -150,7 +149,7 @@ } case "reopen" | "reopen_comment" => { @if(comment.action == "reopen_comment"){ - @showFormatedComment(comment) + @showFormattedComment(comment) }
@@ -229,12 +228,43 @@
} case _ => { - @showFormatedComment(comment) + @showFormattedComment(comment) } } } - case comment: CommitComment => { - @gitbucket.core.helper.html.commitcomment(comment, isManageable, repository, pullreq.map(_.commitIdTo)) + case comments: gitbucket.core.model.CommitComments => { + @gitbucket.core.helper.html.commitcomments(comments, isManageable, repository, pullreq.map(_.commitIdTo)) + } + case comment: gitbucket.core.model.CommitComment => { +
+
+ @helpers.avatar(comment.commentedUserName, 20) + @helpers.user(comment.commentedUserName, styleClass="username strong") + + commented + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) + on + @comment.commitId.substring(0, 7) + + @if((isManageable || context.loginAccount.map(_.userName == comment.commentedUserName).getOrElse(false))){ + +   + + + } +
+
+ @helpers.markdown( + markdown = comment.content, + repository = repository, + enableWikiLink = false, + enableRefsLink = true, + enableLineBreaks = true, + enableTaskList = true, + hasWritePermission = isManageable + ) +
+
} } + +} diff --git a/src/main/twirl/gitbucket/core/pulls/files.scala.html b/src/main/twirl/gitbucket/core/pulls/files.scala.html new file mode 100644 index 0000000..e58cccd --- /dev/null +++ b/src/main/twirl/gitbucket/core/pulls/files.scala.html @@ -0,0 +1,22 @@ +@(issue: gitbucket.core.model.Issue, + pullreq: gitbucket.core.model.PullRequest, + diffs: Seq[gitbucket.core.util.JGitUtil.DiffInfo], + commits: Seq[gitbucket.core.util.JGitUtil.CommitInfo], + comments: Seq[gitbucket.core.model.Comment], + isManageable: Boolean, + repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context) +@gitbucket.core.pulls.html.menu("files", issue, pullreq, commits, comments, isManageable, repository) { + @gitbucket.core.helper.html.diff( + diffs, + repository, + commits.headOption.map(_.id), + commits.lastOption.map(_.id), + true, + Some(pullreq.issueId), + isManageable, + true + ) + +} diff --git a/src/main/twirl/gitbucket/core/pulls/menu.scala.html b/src/main/twirl/gitbucket/core/pulls/menu.scala.html new file mode 100644 index 0000000..5fc8c5e --- /dev/null +++ b/src/main/twirl/gitbucket/core/pulls/menu.scala.html @@ -0,0 +1,85 @@ +@(active: String, + issue: gitbucket.core.model.Issue, + pullreq: gitbucket.core.model.PullRequest, + commits: Seq[gitbucket.core.util.JGitUtil.CommitInfo], + comments: Seq[gitbucket.core.model.Comment], + isManageable: Boolean, + repository: gitbucket.core.service.RepositoryService.RepositoryInfo, + flash: Map[String, String] = Map.empty)(body: => Html)(implicit context: gitbucket.core.controller.Context) +@import gitbucket.core.view.helpers +@import gitbucket.core.model.IssueComment +@gitbucket.core.html.main(s"${issue.title} - Pull request #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)) { + @gitbucket.core.html.menu("pulls", repository) { +
+
+ @if(isManageable || context.loginAccount.map(_.userName == issue.openedUserName).getOrElse(false)) { + Edit + } + @if(context.loginAccount.isDefined) { + New pull request + } +
+ +

+ + @issue.title + #@issue.issueId + + +

+
+
+ @if(issue.closed) { + @comments.flatMap @{ + case comment: IssueComment => Some(comment) + case _ => None + }.find(_.action == "merge").map { comment => + Merged + + @helpers.user(comment.commentedUserName, styleClass = "username strong") + merged @commits.size @helpers.plural(commits.size, "commit") + into @pullreq.userName:@pullreq.branch from @pullreq.requestUserName + :@pullreq.requestBranch + @gitbucket.core.helper.html.datetimeago(comment.registeredDate) + + }.getOrElse { + Closed + + @helpers.user(issue.openedUserName, styleClass = "username strong") + wants to merge @commits.size @helpers.plural(commits.size, "commit") + into @pullreq.userName:@pullreq.branch from @pullreq.requestUserName + :@pullreq.requestBranch + + } + } else { + Open + + @helpers.user(issue.openedUserName, styleClass = "username strong") + wants to merge @commits.size @helpers.plural(commits.size, "commit") + into @pullreq.userName:@pullreq.branch from @pullreq.requestUserName + :@pullreq.requestBranch + + } +
+ +
+ @flash.get("error").map { error => +
@error
+ } + @flash.get("info").map { info => +
@info
+ } + @body +
+ } +} diff --git a/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html b/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html index 78e21fa..ebaa017 100644 --- a/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html +++ b/src/main/twirl/gitbucket/core/pulls/mergeguide.scala.html @@ -5,7 +5,7 @@ forkedRepository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context) @import gitbucket.core.view.helpers
-
+
@if(!status.statuses.isEmpty){
diff --git a/src/main/twirl/gitbucket/core/pulls/pullreq.scala.html b/src/main/twirl/gitbucket/core/pulls/pullreq.scala.html index 604b0d2..93f9fbf 100644 --- a/src/main/twirl/gitbucket/core/pulls/pullreq.scala.html +++ b/src/main/twirl/gitbucket/core/pulls/pullreq.scala.html @@ -17,6 +17,7 @@ @import gitbucket.core.view.helpers @import gitbucket.core.model.IssueComment @import gitbucket.core.model.CommitComment +@* @gitbucket.core.html.main(s"${issue.title} - Pull request #${issue.issueId} - ${repository.owner}/${repository.name}", Some(repository)){ @gitbucket.core.html.menu("pulls", repository){ @defining(dayByDayCommits.flatten){ commits => @@ -73,7 +74,7 @@
@if(commits.nonEmpty){ - @gitbucket.core.pulls.html.commits(dayByDayCommits, Some(comments), repository) + @gitbucket.core.pulls.html.commits(dayByDayCommits, repository) }
@@ -157,3 +158,4 @@ }); }); +*@ diff --git a/src/main/twirl/gitbucket/core/repo/commentform.scala.html b/src/main/twirl/gitbucket/core/repo/commentform.scala.html index a681862..7261f08 100644 --- a/src/main/twirl/gitbucket/core/repo/commentform.scala.html +++ b/src/main/twirl/gitbucket/core/repo/commentform.scala.html @@ -49,6 +49,15 @@ $($form.serializeArray()).each(function(i, v) { param[v.name] = v.value; }); + + @if(newLineNumber.isDefined){ + var diff = getDiffData($('table[filename="@fileName"] table.diff tr:has(th.line-num.newline[line-number=@newLineNumber])')); + param['diff'] = JSON.stringify(diff); + } else if(oldLineNumber.isDefined){ + var diff = getDiffData($('table[filename="@fileName"] table.diff tr:has(th.line-num.oldline[line-number=@oldLineNumber])')); + param['diff'] = JSON.stringify(diff); + } + $.ajax({ url: '@helpers.url(repository)/commit/@commitId/comment/_data/new', type: 'POST', @@ -85,10 +94,10 @@ $tr.after(tmp); } - $('#comment-list').append(data); - if (typeof $('#show-notes')[0] !== 'undefined' && !$('#show-notes')[0].checked) { - $('#comment-list').children('.inline-comment').hide(); - } + // $('#comment-list').append(data); + // if (typeof $('#show-notes')[0] !== 'undefined' && !$('#show-notes')[0].checked) { + // $('#comment-list').children('.inline-comment').hide(); + // } }).fail(function(req) { $('.btn-inline-comment').removeAttr('disabled'); $('#error-content', $form).html($.parseJSON(req.responseText).content); @@ -96,7 +105,6 @@ }); function getInlineContainer() { - console.log(window.viewType); if (window.viewType == 0) { if(@newLineNumber.isDefined){ return $(''); @@ -107,5 +115,31 @@ } return $(''); } + + function getDiffData(tr){ + var result = []; + var count = 0; + + while(tr && count < 4){ + var oldTh = tr.find('th.oldline'); + var newTh = tr.find('th.newline'); + + if(!oldTh.attr('line-number') && !newTh.attr('line-number')){ + break; + } + + result.unshift({ + 'oldLine': oldTh.attr('line-number'), + 'newLine': newTh.attr('line-number'), + 'type': tr.has('td.insert').length > 0 ? 'insert' : tr.has('td.delete').length > 0 ? 'delete' : 'equal', + 'text': tr.find('td>span').text() + }) + + tr = tr.prev('tr:has(th.line-num)'); + count++; + } + + return result; + } } diff --git a/src/main/twirl/gitbucket/core/repo/commit.scala.html b/src/main/twirl/gitbucket/core/repo/commit.scala.html index 0658bbf..19f0782 100644 --- a/src/main/twirl/gitbucket/core/repo/commit.scala.html +++ b/src/main/twirl/gitbucket/core/repo/commit.scala.html @@ -1,3 +1,4 @@ +@import gitbucket.core.model.CommitComment @(commitId: String, commit: gitbucket.core.util.JGitUtil.CommitInfo, branches: List[String], @@ -87,7 +88,20 @@ Show line notes below
- @gitbucket.core.issues.html.commentlist(None, comments, hasWritePermission, repository, None) + @gitbucket.core.issues.html.commentlist( + None, + comments.filter(_.asInstanceOf[gitbucket.core.model.CommitComment].fileName.isEmpty), + hasWritePermission, + repository, + None) +
+ @gitbucket.core.issues.html.commentlist( + None, + comments.filter(_.asInstanceOf[gitbucket.core.model.CommitComment].fileName.isDefined), + hasWritePermission, + repository, + None) +
@gitbucket.core.repo.html.commentform(commitId = commitId, hasWritePermission = hasWritePermission, repository = repository) } diff --git a/src/main/twirl/gitbucket/core/repo/editcomment.scala.html b/src/main/twirl/gitbucket/core/repo/editcomment.scala.html index 9e3d3d0..9ae5965 100644 --- a/src/main/twirl/gitbucket/core/repo/editcomment.scala.html +++ b/src/main/twirl/gitbucket/core/repo/editcomment.scala.html @@ -14,7 +14,7 @@ elastic = true, tabIndex = 1 ) -
+
diff --git a/src/main/webapp/assets/common/css/gitbucket.css b/src/main/webapp/assets/common/css/gitbucket.css index af71d81..9b196f1 100644 --- a/src/main/webapp/assets/common/css/gitbucket.css +++ b/src/main/webapp/assets/common/css/gitbucket.css @@ -772,20 +772,24 @@ margin-left: 50px; } -div.issue-comment-box, div.commit-comment-box { - margin-bottom: 15px; -} - -div.issue-comment-box > div.panel-body, -div.commit-comment-box > div.panel-body { - padding: 8px; -} - - -div.issue-comment-box textarea { +div.commit-comment-box textarea, +div.issue-comment-box textarea{ height: 100px; max-height: 300px; } +/* +div.commit-comment-box.panel-body { + padding-top: 8px; + padding-bottom: 0px; +} +*/ +div.commit-comment-box div.tabbable { + margin-top: 5px; +} + +div.reply-comment-box { + margin-bottom: 5px; +} div.issue-comment-action { padding-bottom: 10px; @@ -1172,6 +1176,7 @@ .not-diff > .comment-box-container { white-space: normal; line-height: initial; + padding-top: 8px; padding-left: 10px; padding-right: 10px; }