@@ -258,6 +258,15 @@ issues = Issues | |||
commits = Commits | |||
releases = Releases | |||
commits.commits = Commits | |||
commits.search = Search commits | |||
commits.find = Find | |||
commits.author = Author | |||
commits.message = Message | |||
commits.date = Date | |||
commits.older = Older | |||
commits.newer = Newer | |||
settings = Settings | |||
settings.options = Options | |||
settings.collaboration = Collaboration |
@@ -258,6 +258,15 @@ issues = 工单管理 | |||
commits = 提交历史 | |||
releases = 版本发布 | |||
commits.commits = 次代码提交 | |||
commits.search = 搜索提交历史 | |||
commits.find = 查找 | |||
commits.author = 作者 | |||
commits.message = 备注 | |||
commits.date = 提交日期 | |||
commits.older = 更旧的提交 | |||
commits.newer = 更新的提交 | |||
settings = 仓库设置 | |||
settings.options = 基本设置 | |||
settings.collaboration = 管理协作者 |
@@ -1081,6 +1081,13 @@ func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) { | |||
return repos, err | |||
} | |||
// __ __ __ .__ | |||
// / \ / \_____ _/ |_ ____ | |__ | |||
// \ \/\/ /\__ \\ __\/ ___\| | \ | |||
// \ / / __ \| | \ \___| Y \ | |||
// \__/\ / (____ /__| \___ >___| / | |||
// \/ \/ \/ \/ | |||
// Watch is connection request for receiving repository notifycation. | |||
type Watch struct { | |||
Id int64 | |||
@@ -1151,6 +1158,13 @@ func NotifyWatchers(act *Action) error { | |||
return nil | |||
} | |||
// _________ __ | |||
// / _____// |______ _______ | |||
// \_____ \\ __\__ \\_ __ \ | |||
// / \| | / __ \| | \/ | |||
// /_______ /|__| (____ /__| | |||
// \/ \/ | |||
type Star struct { | |||
Id int64 | |||
Uid int64 `xorm:"UNIQUE(s)"` |
@@ -5,6 +5,7 @@ | |||
package models | |||
import ( | |||
"container/list" | |||
"crypto/sha256" | |||
"encoding/hex" | |||
"errors" | |||
@@ -513,6 +514,34 @@ func GetUserIdsByNames(names []string) []int64 { | |||
return ids | |||
} | |||
// UserCommit represtns a commit with validation of user. | |||
type UserCommit struct { | |||
UserName string | |||
*git.Commit | |||
} | |||
// ValidCommitsWithEmails checks if authors' e-mails of commits are correcponding to users. | |||
func ValidCommitsWithEmails(oldCommits *list.List) *list.List { | |||
newCommits := list.New() | |||
e := oldCommits.Front() | |||
for e != nil { | |||
c := e.Value.(*git.Commit) | |||
uname := "" | |||
u, err := GetUserByEmail(c.Author.Email) | |||
if err == nil { | |||
uname = u.Name | |||
} | |||
newCommits.PushBack(UserCommit{ | |||
UserName: uname, | |||
Commit: c, | |||
}) | |||
e = e.Next() | |||
} | |||
return newCommits | |||
} | |||
// GetUserByEmail returns the user object by given e-mail if exists. | |||
func GetUserByEmail(email string) (*User, error) { | |||
if len(email) == 0 { |
@@ -20,6 +20,11 @@ img.avatar-16 { | |||
height: 16px; | |||
vertical-align: middle; | |||
} | |||
img.avatar-20 { | |||
width: 20px; | |||
height: 20px; | |||
vertical-align: middle; | |||
} | |||
img.avatar-24 { | |||
width: 24px; | |||
height: 24px; | |||
@@ -1446,6 +1451,27 @@ The register and sign-in page style | |||
width: 100%; | |||
list-style: none; | |||
} | |||
#commits-list { | |||
padding-top: 20px; | |||
} | |||
.commit-list th { | |||
background-color: #FFF; | |||
line-height: 28px !important; | |||
} | |||
.commit-list .date { | |||
width: 120px; | |||
} | |||
.commit-list .author { | |||
padding-left: 20px; | |||
min-width: 180px; | |||
} | |||
.commit-list .author img { | |||
margin-top: -4px; | |||
} | |||
.commit-list .sha a { | |||
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace; | |||
font-size: 14px; | |||
} | |||
#admin-wrapper, | |||
#setting-wrapper { | |||
padding-bottom: 100px; |
@@ -732,6 +732,10 @@ ul.menu-radius > li:last-child > a { | |||
.label-green { | |||
background-color: #65ad4e; | |||
} | |||
.label-green:hover { | |||
background-color: #71bf57; | |||
color: #FFF; | |||
} | |||
.label-orange { | |||
background-color: #df7514; | |||
} |
@@ -30,6 +30,11 @@ img.avatar-16 { | |||
height: 16px; | |||
vertical-align: middle; | |||
} | |||
img.avatar-20 { | |||
width: 20px; | |||
height: 20px; | |||
vertical-align: middle; | |||
} | |||
img.avatar-24 { | |||
width: 24px; | |||
height: 24px; |
@@ -6,14 +6,12 @@ | |||
/* repository main */ | |||
#repo-wrapper { | |||
padding-bottom: 100px; | |||
padding-bottom: 100px; | |||
} | |||
#repo-header { | |||
height: 69px; | |||
border-bottom: 1px solid@repoHeaderBorderColor; | |||
background-color: @repoHeaderBgColor; | |||
height: 69px; | |||
border-bottom: 1px solid@repoHeaderBorderColor; | |||
background-color: @repoHeaderBgColor; | |||
} | |||
#repo-header-name { | |||
line-height: 66px; | |||
@@ -494,4 +492,27 @@ | |||
.setting-list { | |||
width: 100%; | |||
list-style: none; | |||
} | |||
#commits-list { | |||
padding-top: 20px; | |||
} | |||
.commit-list { | |||
th { | |||
background-color: #FFF; | |||
line-height: 28px !important; | |||
} | |||
.date { | |||
width: 120px; | |||
} | |||
.author { | |||
padding-left: 20px; | |||
min-width: 180px; | |||
img { | |||
margin-top: -4px; | |||
} | |||
} | |||
.sha a { | |||
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace; | |||
font-size: 14px; | |||
} | |||
} |
@@ -16,11 +16,13 @@ | |||
.label-gray { | |||
background-color: @labelGrayColor; | |||
} | |||
.label-green { | |||
background-color: @labelGreenColor; | |||
background-color: @labelGreenColor; | |||
&:hover { | |||
background-color: @btnHoverGreenColor; | |||
color: #FFF; | |||
} | |||
} | |||
.label-orange { | |||
background-color: @labelOrangeColor; | |||
} |
@@ -56,12 +56,14 @@ func Commits(ctx *middleware.Context) { | |||
} | |||
// Both `git log branchName` and `git log commitId` work. | |||
ctx.Data["Commits"], err = ctx.Repo.Commit.CommitsByRange(page) | |||
commits, err := ctx.Repo.Commit.CommitsByRange(page) | |||
if err != nil { | |||
ctx.Handle(500, "CommitsByRange", err) | |||
return | |||
} | |||
commits = models.ValidCommitsWithEmails(commits) | |||
ctx.Data["Commits"] = commits | |||
ctx.Data["Username"] = userName | |||
ctx.Data["Reponame"] = repoName | |||
ctx.Data["CommitCount"] = commitsCount |
@@ -45,8 +45,8 @@ | |||
</table> | |||
{{if or .LastPageNum .NextPageNum}} | |||
<ul class="pagination"> | |||
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.LastPageNum}}">« Prev.</a></li>{{end}} | |||
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.NextPageNum}}">» Next</a></li>{{end}} | |||
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.LastPageNum}}">« {{.i18n.Tr "admin.prev"}}</a></li>{{end}} | |||
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.NextPageNum}}">» {{.i18n.Tr "admin.next"}}</a></li>{{end}} | |||
</ul> | |||
{{end}} | |||
</div> |
@@ -1,8 +1,9 @@ | |||
{{template "base/head" .}} | |||
{{template "base/navbar" .}} | |||
{{template "repo/nav" .}} | |||
{{template "repo/toolbar" .}} | |||
<div id="body" class="container"> | |||
{{template "repo/commits_table" .}} | |||
{{template "ng/base/head" .}} | |||
{{template "ng/base/header" .}} | |||
<div id="repo-wrapper"> | |||
{{template "repo/header" .}} | |||
<div class="container clear"> | |||
{{template "repo/commits_table" .}} | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
{{template "ng/base/footer" .}} |
@@ -1,23 +1,19 @@ | |||
<div id="commits"> | |||
<div class="panel panel-default commit-box info-box"> | |||
<div class="panel-heading info-head"> | |||
<form class="search pull-right col-md-3" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> | |||
<div class="input-group"> | |||
<input class="form-control search" type="search" placeholder="search commit" name="q" value="{{.Keyword}}" /> | |||
<div class="input-group-btn"> | |||
<button type="submit" class="btn btn-default">Find</button> | |||
</div> | |||
</div> | |||
<div id="commits-list"> | |||
<div class="panel panel-radius"> | |||
<div class="panel-header"> | |||
<form class="search pull-right" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> | |||
<input class="ipt ipt-radius" type="search" name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" /> | |||
<button class="btn btn-black btn-small btn-radius">{{.i18n.Tr "repo.commits.find"}}</button> | |||
</form> | |||
<h4>{{.CommitCount}} Commits</h4> | |||
<h4>{{.CommitCount}} {{.i18n.Tr "repo.commits.commits"}}</h4> | |||
</div> | |||
<table class="panel-footer table commit-list table table-striped"> | |||
<table class="panel-body table commit-list table-striped"> | |||
<thead> | |||
<tr> | |||
<th class="author">Author</th> | |||
<th class="author">{{.i18n.Tr "repo.commits.author"}}</th> | |||
<th class="sha">SHA1</th> | |||
<th class="message">Message</th> | |||
<th class="date">Date</th> | |||
<th class="message">{{.i18n.Tr "repo.commits.message"}}</th> | |||
<th class="date">{{.i18n.Tr "repo.commits.date"}}</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
@@ -26,8 +22,8 @@ | |||
{{$r := List .Commits}} | |||
{{range $r}} | |||
<tr> | |||
<td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="{{AppSubUrl}}/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td> | |||
<td class="sha"><a rel="nofollow" class="label label-success" href="{{AppSubUrl}}/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td> | |||
<td class="author"><img class="avatar-20" src="{{AvatarLink .Author.Email}}" alt=""/> {{if .UserName}}<a href="{{AppSubUrl}}/{{.UserName}}">{{.Author.Name}}</a>{{else}}{{.Author.Name}}{{end}}</td> | |||
<td class="sha"><a rel="nofollow" class="label label-green" href="{{AppSubUrl}}/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td> | |||
<td class="message">{{.Summary}} </td> | |||
<td class="date">{{TimeSince .Author.When $.Lang}}</td> | |||
</tr> | |||
@@ -35,8 +31,10 @@ | |||
</tbody> | |||
</table> | |||
</div> | |||
{{if not .IsSearchPage}}<ul class="pagination" id="commits-pager"> | |||
{{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}} | |||
{{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}} | |||
</ul>{{end}} | |||
{{if not .IsSearchPage}} | |||
<ul class="pagination"> | |||
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« {{.i18n.Tr "repo.commits.newer"}}</a></li>{{end}} | |||
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» {{.i18n.Tr "repo.commits.older"}}</a></li>{{end}} | |||
</ul> | |||
{{end}} | |||
</div> |