Page: User profile

This commit is contained in:
Unknwon 2014-09-25 19:33:39 -04:00
parent f69761563b
commit 71e4689d11
12 changed files with 275 additions and 79 deletions

View File

@ -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. 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] [settings]
profile = Profile profile = Profile
password = Password password = Password

View File

@ -166,6 +166,15 @@ org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先
still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试! still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试!
[user]
change_avatar = 到 gravatar.com 上修改您的头像
join_on = 加入于
repositories = 仓库列表
activity = 公开活动
followers = 关注者
starred = 已点赞
following = 关注中
[settings] [settings]
profile = 个人信息 profile = 个人信息
password = 修改密码 password = 修改密码

View File

@ -1197,16 +1197,20 @@ func StarRepo(uid, repoId int64, star bool) (err error) {
} }
if _, err = x.Insert(&Star{Uid: uid, RepoId: repoId}); err != nil { if _, err = x.Insert(&Star{Uid: uid, RepoId: repoId}); err != nil {
return err 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 { } else {
if !IsStaring(uid, repoId) { if !IsStaring(uid, repoId) {
return nil return nil
} }
if _, err = x.Delete(&Star{0, uid, repoId}); err != nil { if _, err = x.Delete(&Star{0, uid, repoId}); err != nil {
return err 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 return err
} }

View File

@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
@ -90,7 +91,7 @@ func (u *User) DashboardLink() string {
// HomeLink returns the user home page link. // HomeLink returns the user home page link.
func (u *User) HomeLink() string { func (u *User) HomeLink() string {
return setting.AppSubUrl + "/user/" + u.Name return "/" + path.Join(setting.AppSubUrl, u.Name)
} }
// AvatarLink returns user gravatar link. // AvatarLink returns user gravatar link.

View File

@ -2074,3 +2074,56 @@ textarea#issue-add-content {
.admin-dl-horizontal > dd { .admin-dl-horizontal > dd {
margin-left: 240px; 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;
}

View File

@ -608,6 +608,13 @@ function initInstall() {
}()); }());
} }
function initProfile() {
// Avatar.
$('#profile-avatar').tipsy({
fade: true
});
}
$(document).ready(function () { $(document).ready(function () {
Gogs.AppSubUrl = $('head').data('suburl'); Gogs.AppSubUrl = $('head').data('suburl');
initCore(); initCore();
@ -644,6 +651,9 @@ $(document).ready(function () {
if ($('#install-form').length) { if ($('#install-form').length) {
initInstall(); initInstall();
} }
if ($('#user-profile-page').length) {
initProfile();
}
$('#dashboard-sidebar-menu').tabs(); $('#dashboard-sidebar-menu').tabs();
$('#pull-issue-preview').markdown_preview(".issue-add-comment"); $('#pull-issue-preview').markdown_preview(".issue-add-comment");

File diff suppressed because one or more lines are too long

View File

@ -8,3 +8,4 @@
@import "gogs/issue"; @import "gogs/issue";
@import "gogs/organization"; @import "gogs/organization";
@import "gogs/admin"; @import "gogs/admin";
@import "gogs/profile";

View File

@ -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;
}
}
}

View File

@ -48,7 +48,7 @@
</div> </div>
{{end}} {{end}}
</div> </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"> <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> <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}} {{if not .ContextUser.IsOrganization}}

View File

@ -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}}

View File

@ -1,81 +1,91 @@
{{template "base/head" .}} {{template "ng/base/head" .}}
{{template "base/navbar" .}} {{template "ng/base/header" .}}
<div id="body" class="container" data-page="user"> <div class="main-wrapper">
<div id="user-profile" class="col-md-3"> <div id="user-profile-page" class="container clear">
<div class="profile-avatar text-center"> <div class="grid-1-4 left">
<a href="http://gravatar.com/emails/" class="center-block" data-toggle="tooltip" data-placement="bottom" title="Change your avatar at gravatar.com"> <div class="text-center">
<img id="user-avatar" src="{{.Owner.AvatarLink}}?s=200" alt="user-avatar" title="{{.Owner.Name}}"/> <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> </a>
{{if .Owner.FullName}}<span id="user-full-name" class="center-block">{{.Owner.FullName}}</span>{{end}} <div id="profile-name">
<span id="user-name" class="center-block">{{.Owner.Name}}</span> {{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>
<div class="profile-info"> <div class="profile-info">
<ul class="list-group"> <hr>
<ul class="list-no-style">
{{if .Owner.Location}} {{if .Owner.Location}}
<li class="list-group-item"><i class="fa fa-thumb-tack"></i>{{.Owner.Location}}</li> <li class="list-group-item"><i class="octicon octicon-location"></i>&nbsp;&nbsp;{{.Owner.Location}}</li>
{{end}} {{end}}
{{if .Owner.Email}} {{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> <li class="list-group-item"><i class="octicon octicon-mail"></i>&nbsp;&nbsp;<a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a></li>
{{end}} {{end}}
{{if .Owner.Website}} {{if .Owner.Website}}
<li class="list-group-item"><i class="fa fa-link"></i><a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li> <li class="list-group-item"><i class="octicon octicon-link"></i>&nbsp;&nbsp;<a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li>
{{end}} {{end}}
<li class="list-group-item"><i class="fa fa-clock-o"></i>Joined on {{DateFormat .Owner.Created "M d, Y"}}</li> <li class="list-group-item"><i class="octicon octicon-clock"></i>&nbsp;&nbsp;{{.i18n.Tr "user.join_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>
</li>
<hr> -->
</ul> </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> </div>
<div id="user-activity" class="col-md-9"> <div class="grid-3-4 left">
<ul class="nav nav-tabs" id="user-act-tabs"> <ul class="menu menu-line" id="profile-header">
<li{{if not .TabName}} class="active"{{end}}><a href="{{.Owner.HomeLink}}"><i class="fa fa-gittip"></i>Repositories</a></li> <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> <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>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
{{if eq .TabName "activity"}} {{if eq .TabName "activity"}}
<div class="tab-pane active"> <div class="tab-pane active" id="dashboard-news">
<ul class="list-unstyled activity-list"> <br>
{{range .Feeds}} {{template "user/dashboard/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>
{{else}}
<li>No public activity yet.</li>
{{end}}
</ul>
</div> </div>
{{else}} {{else}}
<div class="tab-pane active"> <div class="tab-pane active">
<ul class="list-unstyled repo-list"> <div id="org-repo-list">
{{range .Repos}} {{range .Repos}}
<li> {{if not .IsPrivate}}
<div class="meta pull-right"><!-- <i class="fa fa-star"></i> {{.NumStars}} --> <i class="fa fa-code-fork"></i> {{.NumForks}}</div> <div class="org-repo-item">
<h4> <ul class="org-repo-status right">
<a href="{{AppSubUrl}}/{{$.Owner.Name}}/{{.Name}}">{{.Name}}{{if .IsPrivate}} <span class="label label-default">Private</span>{{end}}</a> <li><i class="octicon octicon-star"></i> {{.NumStars}}</li>
</h4> <li><i class="octicon octicon-git-branch"></i> {{.NumForks}}</li>
<p class="desc">{{.Description}}</p>
<div class="info">Last updated {{TimeSince .Updated $.Lang}}</div>
</li>
{{end}}
</ul> </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> </div>
{{end}} {{end}}
{{end}}
</div>
</div>
{{end}}
</div>
</div> </div>
</div> </div>
</div> </div>
{{template "base/footer" .}} {{template "ng/base/footer" .}}