@@ -166,6 +166,15 @@ org_still_own_repo = This organization still have ownership of repository, you h | |||
still_own_user = This authentication still has used by some users, you should move them and then delete again. | |||
[user] | |||
change_avatar = Change your avatar at gravatar.com | |||
join_on = Joined on | |||
repositories = Repositories | |||
activity = Public Activity | |||
followers = Followers | |||
starred = Starred | |||
following = Following | |||
[settings] | |||
profile = Profile | |||
password = Password |
@@ -166,6 +166,15 @@ org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先 | |||
still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试! | |||
[user] | |||
change_avatar = 到 gravatar.com 上修改您的头像 | |||
join_on = 加入于 | |||
repositories = 仓库列表 | |||
activity = 公开活动 | |||
followers = 关注者 | |||
starred = 已点赞 | |||
following = 关注中 | |||
[settings] | |||
profile = 个人信息 | |||
password = 修改密码 |
@@ -1197,16 +1197,20 @@ func StarRepo(uid, repoId int64, star bool) (err error) { | |||
} | |||
if _, err = x.Insert(&Star{Uid: uid, RepoId: repoId}); err != nil { | |||
return err | |||
} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoId); err != nil { | |||
return err | |||
} | |||
_, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoId) | |||
_, err = x.Exec("UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", uid) | |||
} else { | |||
if !IsStaring(uid, repoId) { | |||
return nil | |||
} | |||
if _, err = x.Delete(&Star{0, uid, repoId}); err != nil { | |||
return err | |||
} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoId); err != nil { | |||
return err | |||
} | |||
_, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoId) | |||
_, err = x.Exec("UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", uid) | |||
} | |||
return err | |||
} |
@@ -11,6 +11,7 @@ import ( | |||
"errors" | |||
"fmt" | |||
"os" | |||
"path" | |||
"path/filepath" | |||
"strings" | |||
"time" | |||
@@ -90,7 +91,7 @@ func (u *User) DashboardLink() string { | |||
// HomeLink returns the user home page link. | |||
func (u *User) HomeLink() string { | |||
return setting.AppSubUrl + "/user/" + u.Name | |||
return "/" + path.Join(setting.AppSubUrl, u.Name) | |||
} | |||
// AvatarLink returns user gravatar link. |
@@ -2074,3 +2074,56 @@ textarea#issue-add-content { | |||
.admin-dl-horizontal > dd { | |||
margin-left: 240px; | |||
} | |||
.profile-avatar { | |||
width: 200px; | |||
height: 200px; | |||
border-radius: 6px; | |||
} | |||
#profile-name { | |||
padding: 10px 0; | |||
} | |||
#profile-fullname { | |||
font-size: 1.6em; | |||
} | |||
#profile-username { | |||
font-size: 1.6em; | |||
font-weight: bold; | |||
} | |||
.profile-info { | |||
padding: 0 50px; | |||
font-size: 14px; | |||
} | |||
.profile-info ul { | |||
padding-bottom: 10px; | |||
} | |||
.profile-info ul .list-group-item { | |||
background-color: transparent; | |||
padding-top: 5px; | |||
color: #666; | |||
} | |||
.profile-info ul .profile-rel { | |||
width: 31%; | |||
text-align: center; | |||
display: inline-block; | |||
} | |||
.profile-info ul .profile-rel strong { | |||
display: block; | |||
font-size: 28px; | |||
font-weight: bold; | |||
line-height: 1; | |||
} | |||
.profile-info ul .profile-rel p { | |||
font-size: 12px; | |||
} | |||
#profile-header li a { | |||
font-size: 1.2em; | |||
color: #444444; | |||
padding: .4em .8em; | |||
} | |||
#profile-header li a:hover { | |||
background-color: transparent; | |||
color: #d9453d; | |||
} | |||
#profile-header li .current { | |||
border-bottom: 2px solid #D26911; | |||
} |
@@ -608,6 +608,13 @@ function initInstall() { | |||
}()); | |||
} | |||
function initProfile() { | |||
// Avatar. | |||
$('#profile-avatar').tipsy({ | |||
fade: true | |||
}); | |||
} | |||
$(document).ready(function () { | |||
Gogs.AppSubUrl = $('head').data('suburl'); | |||
initCore(); | |||
@@ -644,6 +651,9 @@ $(document).ready(function () { | |||
if ($('#install-form').length) { | |||
initInstall(); | |||
} | |||
if ($('#user-profile-page').length) { | |||
initProfile(); | |||
} | |||
$('#dashboard-sidebar-menu').tabs(); | |||
$('#pull-issue-preview').markdown_preview(".issue-add-comment"); |
@@ -7,4 +7,5 @@ | |||
@import "gogs/settings"; | |||
@import "gogs/issue"; | |||
@import "gogs/organization"; | |||
@import "gogs/admin"; | |||
@import "gogs/admin"; | |||
@import "gogs/profile"; |
@@ -0,0 +1,57 @@ | |||
.profile-avatar { | |||
width: 200px; | |||
height: 200px; | |||
border-radius: 6px; | |||
} | |||
#profile-name { | |||
padding: 10px 0; | |||
} | |||
#profile-fullname { | |||
font-size: 1.6em; | |||
} | |||
#profile-username { | |||
font-size: 1.6em; | |||
font-weight: bold; | |||
} | |||
.profile-info { | |||
padding: 0 50px; | |||
font-size: 14px; | |||
ul { | |||
padding-bottom: 10px; | |||
.list-group-item { | |||
background-color: transparent; | |||
padding-top: 5px; | |||
color: #666; | |||
} | |||
.profile-rel { | |||
width: 31%; | |||
text-align: center; | |||
display: inline-block; | |||
strong { | |||
display: block; | |||
font-size: 28px; | |||
font-weight: bold; | |||
line-height: 1; | |||
} | |||
p { | |||
font-size: 12px; | |||
} | |||
} | |||
} | |||
} | |||
#profile-header { | |||
li { | |||
a { | |||
font-size: 1.2em; | |||
color: #444444; | |||
padding: .4em .8em; | |||
&:hover { | |||
background-color: transparent; | |||
color: @dashboardHeaderLinkHoverColor; | |||
} | |||
} | |||
.current { | |||
border-bottom: 2px solid #D26911; | |||
} | |||
} | |||
} |
@@ -48,7 +48,7 @@ | |||
</div> | |||
{{end}} | |||
</div> | |||
<div id="dashboard-sidebar" class="right grid-1-3"> | |||
<div class="right grid-1-3" id="dashboard-sidebar"> | |||
<ul id="dashboard-sidebar-menu" class="menu menu-line"> | |||
<li class="js-tab-nav js-tab-nav-show first" data-tab-target="#dashboard-my-repo"><a href="#">{{.i18n.Tr "repository"}}</a></li> | |||
{{if not .ContextUser.IsOrganization}} |
@@ -0,0 +1,42 @@ | |||
{{range .Feeds}} | |||
<div class="news clear"> | |||
<div class="avatar left"> | |||
<img class="avatar-30" src="{{AvatarLink .GetActEmail}}" alt=""> | |||
</div> | |||
<div class="content left {{if eq .GetOpType 5}}push-news{{end}} grid-4-5"> | |||
<p class="text-bold"> | |||
<a href="{{AppSubUrl}}/{{.GetActUserName}}">{{.GetActUserName}}</a> | |||
{{if eq .GetOpType 1}} | |||
{{$.i18n.Tr "action.create_repo" AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} | |||
{{else if eq .GetOpType 5}} | |||
{{$.i18n.Tr "action.commit_repo" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} | |||
{{else if eq .GetOpType 6}} | |||
{{ $index := index .GetIssueInfos 0}} | |||
{{$.i18n.Tr "action.create_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}} | |||
{{else if eq .GetOpType 8}} | |||
{{$.i18n.Tr "action.transfer_repo" .GetRepoName AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} | |||
{{else if eq .GetOpType 10}} | |||
{{ $index := index .GetIssueInfos 0}} | |||
{{$.i18n.Tr "action.comment_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}} | |||
{{end}} | |||
</p> | |||
{{if eq .GetOpType 5}} | |||
<div class="news-content content"> | |||
<ul class="list-no-style"> | |||
{{ $push := ActionContent2Commits .}} | |||
{{ $repoLink := .GetRepoLink}} | |||
{{range $push.Commits}} | |||
<li><img class="avatar-16" src="{{AvatarLink .AuthorEmail}}?s=16"> <a href="{{AppSubUrl}}/{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text-truncate grid-4-5">{{.Message}}</span></li> | |||
{{end}} | |||
</ul> | |||
</div> | |||
{{else if eq .GetOpType 6}} | |||
<p class="news-content comment-news">{{index .GetIssueInfos 1}}</p> | |||
{{else if eq .GetOpType 10}} | |||
<p class="news-content comment-news">{{index .GetIssueInfos 1}}</p> | |||
{{end}} | |||
<p class="news-time text-italic">{{TimeSince .GetCreate $.i18n.Lang}}</p> | |||
</div> | |||
<i class="mega-octicon octicon-{{ActionIcon .GetOpType}} right"></i> | |||
</div> | |||
{{end}} |
@@ -1,81 +1,91 @@ | |||
{{template "base/head" .}} | |||
{{template "base/navbar" .}} | |||
<div id="body" class="container" data-page="user"> | |||
<div id="user-profile" class="col-md-3"> | |||
<div class="profile-avatar text-center"> | |||
<a href="http://gravatar.com/emails/" class="center-block" data-toggle="tooltip" data-placement="bottom" title="Change your avatar at gravatar.com"> | |||
<img id="user-avatar" src="{{.Owner.AvatarLink}}?s=200" alt="user-avatar" title="{{.Owner.Name}}"/> | |||
</a> | |||
{{if .Owner.FullName}}<span id="user-full-name" class="center-block">{{.Owner.FullName}}</span>{{end}} | |||
<span id="user-name" class="center-block">{{.Owner.Name}}</span> | |||
{{template "ng/base/head" .}} | |||
{{template "ng/base/header" .}} | |||
<div class="main-wrapper"> | |||
<div id="user-profile-page" class="container clear"> | |||
<div class="grid-1-4 left"> | |||
<div class="text-center"> | |||
<a href="http://gravatar.com/emails/" id="profile-avatar" original-title="{{.i18n.Tr "user.change_avatar"}}"> | |||
<img class="profile-avatar" src="{{.Owner.AvatarLink}}?s=200"title="{{.Owner.Name}}"/> | |||
</a> | |||
<div id="profile-name"> | |||
{{if .Owner.FullName}}<span id="profile-fullname" class="center-block">{{.Owner.FullName}}</span><br>{{end}} | |||
<span class="center-block" id="profile-username">{{.Owner.Name}}</span> | |||
</div> | |||
</div> | |||
<div class="profile-info"> | |||
<hr> | |||
<ul class="list-no-style"> | |||
{{if .Owner.Location}} | |||
<li class="list-group-item"><i class="octicon octicon-location"></i> {{.Owner.Location}}</li> | |||
{{end}} | |||
{{if .Owner.Email}} | |||
<li class="list-group-item"><i class="octicon octicon-mail"></i> <a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a></li> | |||
{{end}} | |||
{{if .Owner.Website}} | |||
<li class="list-group-item"><i class="octicon octicon-link"></i> <a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li> | |||
{{end}} | |||
<li class="list-group-item"><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{DateFormat .Owner.Created "M d, Y"}}</li> | |||
</ul> | |||
<hr> | |||
<ul class="list-no-style"> | |||
<li class="list-group-item profile-rel"> | |||
<a class="text-black" href=""> | |||
<strong>{{.Owner.NumFollowers}}</strong> | |||
<p>{{.i18n.Tr "user.followers"}}</p> | |||
</a> | |||
</li> | |||
<li class="list-group-item profile-rel"> | |||
<a class="text-black" href=""> | |||
<strong>{{.Owner.NumStars}}</strong> | |||
<p>{{.i18n.Tr "user.starred"}}</p> | |||
</a> | |||
</li> | |||
<li class="list-group-item profile-rel"> | |||
<a class="text-black" href=""> | |||
<strong>{{.Owner.NumFollowings}}</strong> | |||
<p>{{.i18n.Tr "user.following"}}</p> | |||
</a> | |||
</li> | |||
</ul> | |||
<hr> | |||
</div> | |||
</div> | |||
<div class="profile-info"> | |||
<ul class="list-group"> | |||
{{if .Owner.Location}} | |||
<li class="list-group-item"><i class="fa fa-thumb-tack"></i>{{.Owner.Location}}</li> | |||
{{end}} | |||
{{if .Owner.Email}} | |||
<li class="list-group-item"><i class="fa fa-envelope"></i><a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a></li> | |||
{{end}} | |||
{{if .Owner.Website}} | |||
<li class="list-group-item"><i class="fa fa-link"></i><a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li> | |||
{{end}} | |||
<li class="list-group-item"><i class="fa fa-clock-o"></i>Joined on {{DateFormat .Owner.Created "M d, Y"}}</li> | |||
<!-- <hr> --> | |||
<!-- <li class="list-group-item" style="padding-top: 5px;"> | |||
<div class="profile-rel"> | |||
<div class="col-md-6 followers"> | |||
<strong>123</strong> | |||
<p>followers</p> | |||
</div> | |||
<div class="col-md-6 following"> | |||
<strong>123</strong> | |||
<p>following</p> | |||
</div> | |||
</div> | |||
<div class="grid-3-4 left"> | |||
<ul class="menu menu-line" id="profile-header"> | |||
<li> | |||
<a {{if not .TabName}}class="current"{{end}} href="{{.Owner.HomeLink}}"><i class="octicon octicon-repo"></i> {{.i18n.Tr "user.repositories"}}</a> | |||
</li> | |||
<li> | |||
<a {{if eq .TabName "activity"}}class="current"{{end}} href="{{.Owner.HomeLink}}?tab=activity"><i class="octicon octicon-repo"></i> {{.i18n.Tr "user.activity"}}</a> | |||
</li> | |||
<hr> --> | |||
</ul> | |||
</div> | |||
</div> | |||
<div id="user-activity" class="col-md-9"> | |||
<ul class="nav nav-tabs" id="user-act-tabs"> | |||
<li{{if not .TabName}} class="active"{{end}}><a href="{{.Owner.HomeLink}}"><i class="fa fa-gittip"></i>Repositories</a></li> | |||
<li{{if eq .TabName "activity"}} class="active"{{end}}><a href="{{.Owner.HomeLink}}?tab=activity"><i class="fa fa-rss"></i>Public Activity</a></li> | |||
</ul> | |||
<div class="tab-content"> | |||
{{if eq .TabName "activity"}} | |||
<div class="tab-pane active"> | |||
<ul class="list-unstyled activity-list"> | |||
{{range .Feeds}} | |||
<li> | |||
<i class="icon fa fa-{{ActionIcon .GetOpType}}"></i> | |||
<div class="info"><span class="meta">{{TimeSince .Created $.Lang}}</span><br>{{ActionDesc . | str2html}}</div> | |||
<span class="clearfix"></span> | |||
</li> | |||
<div class="tab-content"> | |||
{{if eq .TabName "activity"}} | |||
<div class="tab-pane active" id="dashboard-news"> | |||
<br> | |||
{{template "user/dashboard/feeds" .}} | |||
</div> | |||
{{else}} | |||
<li>No public activity yet.</li> | |||
{{end}} | |||
</ul> | |||
</div> | |||
{{else}} | |||
<div class="tab-pane active"> | |||
<ul class="list-unstyled repo-list"> | |||
{{range .Repos}} | |||
<li> | |||
<div class="meta pull-right"><!-- <i class="fa fa-star"></i> {{.NumStars}} --> <i class="fa fa-code-fork"></i> {{.NumForks}}</div> | |||
<h4> | |||
<a href="{{AppSubUrl}}/{{$.Owner.Name}}/{{.Name}}">{{.Name}}{{if .IsPrivate}} <span class="label label-default">Private</span>{{end}}</a> | |||
</h4> | |||
<p class="desc">{{.Description}}</p> | |||
<div class="info">Last updated {{TimeSince .Updated $.Lang}}</div> | |||
</li> | |||
<div class="tab-pane active"> | |||
<div id="org-repo-list"> | |||
{{range .Repos}} | |||
{{if not .IsPrivate}} | |||
<div class="org-repo-item"> | |||
<ul class="org-repo-status right"> | |||
<li><i class="octicon octicon-star"></i> {{.NumStars}}</li> | |||
<li><i class="octicon octicon-git-branch"></i> {{.NumForks}}</li> | |||
</ul> | |||
<h2><a href="{{AppSubUrl}}/{{$.Owner.Name}}/{{.Name}}">{{.Name}}</a></h2> | |||
<p class="org-repo-description">{{.Description}}</p> | |||
<p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p> | |||
</div> | |||
{{end}} | |||
{{end}} | |||
</div> | |||
</div> | |||
{{end}} | |||
</ul> | |||
</div> | |||
{{end}} | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
{{template "ng/base/footer" .}} |