Skip to content

Commit 095c30c

Browse files
committed
Fix ::User Profile Page - Project/Packages Tabs Have Inconsistent Layout and Style
1 parent 036fb78 commit 095c30c

File tree

13 files changed

+308
-155
lines changed

13 files changed

+308
-155
lines changed

routers/web/org/projects.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func MustEnableProjects(ctx *context.Context) {
4141

4242
// Projects renders the home page of projects
4343
func Projects(ctx *context.Context) {
44+
shared_user.RenderProfileBigAvatar(ctx)
4445
ctx.Data["Title"] = ctx.Tr("repo.project_board")
4546

4647
sortType := ctx.FormTrim("sort")

routers/web/shared/user/header.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,102 @@
44
package user
55

66
import (
7+
"fmt"
8+
9+
"code.gitea.io/gitea/models/db"
10+
"code.gitea.io/gitea/models/organization"
711
repo_model "code.gitea.io/gitea/models/repo"
12+
user_model "code.gitea.io/gitea/models/user"
813
"code.gitea.io/gitea/modules/context"
914
"code.gitea.io/gitea/modules/git"
15+
"code.gitea.io/gitea/modules/markup"
16+
"code.gitea.io/gitea/modules/markup/markdown"
1017
"code.gitea.io/gitea/modules/setting"
1118
)
1219

20+
// RenderProfileBigAvatar set the context for big avatar view on repo
21+
func RenderProfileBigAvatar(ctx *context.Context) {
22+
// check view permissions
23+
if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) {
24+
ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name))
25+
return
26+
}
27+
28+
// advertise feed via meta tag
29+
ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink()
30+
31+
// Show OpenID URIs
32+
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
33+
if err != nil {
34+
ctx.ServerError("GetUserOpenIDs", err)
35+
return
36+
}
37+
38+
var isFollowing bool
39+
if ctx.Doer != nil {
40+
isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
41+
}
42+
43+
ctx.Data["ContextUser"] = ctx.ContextUser
44+
ctx.Data["OpenIDs"] = openIDs
45+
ctx.Data["IsFollowing"] = isFollowing
46+
47+
if len(ctx.ContextUser.Description) != 0 {
48+
content, err := markdown.RenderString(&markup.RenderContext{
49+
URLPrefix: ctx.Repo.RepoLink,
50+
Metas: map[string]string{"mode": "document"},
51+
GitRepo: ctx.Repo.GitRepo,
52+
Ctx: ctx,
53+
}, ctx.ContextUser.Description)
54+
if err != nil {
55+
ctx.ServerError("RenderString", err)
56+
return
57+
}
58+
ctx.Data["RenderedDescription"] = content
59+
}
60+
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
61+
orgs, err := organization.FindOrgs(organization.FindOrgOptions{
62+
UserID: ctx.ContextUser.ID,
63+
IncludePrivate: showPrivate,
64+
})
65+
if err != nil {
66+
ctx.ServerError("FindOrgs", err)
67+
return
68+
}
69+
ctx.Data["Orgs"] = orgs
70+
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
71+
72+
badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser)
73+
if err != nil {
74+
ctx.ServerError("GetUserBadges", err)
75+
return
76+
}
77+
ctx.Data["Badges"] = badges
78+
79+
pagingNum := setting.UI.User.RepoPagingNum
80+
page := ctx.FormInt("page")
81+
_, numFollowers, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
82+
PageSize: pagingNum,
83+
Page: page,
84+
})
85+
if err != nil {
86+
ctx.ServerError("GetUserFollowers", err)
87+
return
88+
}
89+
ctx.Data["NumFollowers"] = numFollowers
90+
_, numFollowing, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
91+
PageSize: pagingNum,
92+
Page: page,
93+
})
94+
if err != nil {
95+
ctx.ServerError("GetUserFollowing", err)
96+
return
97+
}
98+
ctx.Data["NumFollowing"] = numFollowing
99+
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
100+
ctx.Data["EnableFeed"] = setting.Other.EnableFeed
101+
}
102+
13103
func RenderUserHeader(ctx *context.Context) {
14104
ctx.Data["IsProjectEnabled"] = true
15105
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled

routers/web/user/package.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const (
3636

3737
// ListPackages displays a list of all packages of the context user
3838
func ListPackages(ctx *context.Context) {
39+
shared_user.RenderProfileBigAvatar(ctx)
3940
page := ctx.FormInt("page")
4041
if page <= 1 {
4142
page = 1

templates/org/projects/list.tmpl

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
{{template "base/head" .}}
2-
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
3-
{{template "user/overview/header" .}}
4-
{{template "projects/list" .}}
5-
</div>
2+
{{if .ContextUser.IsOrganization}}
3+
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
4+
{{template "shared/user/profile_big_avatar" .}}
5+
{{template "user/overview/header" .}}
6+
{{template "projects/list" .}}
7+
</div>
8+
{{else}}
9+
<div role="main" aria-label="{{.Title}}" class="page-content user profile">
10+
<div class="ui container">
11+
<div class="ui stackable grid">
12+
<div class="ui four wide column">
13+
{{template "shared/user/profile_big_avatar" .}}
14+
</div>
15+
<div class="ui twelve wide column">
16+
{{template "user/overview/header" .}}
17+
{{template "projects/list" .}}
18+
</div>
19+
</div>
20+
</div>
21+
</div>
22+
{{end}}
623
{{template "base/footer" .}}

templates/package/shared/list.tmpl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<div class="ui container">
1+
<div class="ui {{if .ContextUser.IsOrganization}} container{{end}}">
22
{{template "base/alert" .}}
3-
<form class="ui form ignore-dirty">
3+
<form class="ui form ignore-dirty search-input">
44
<div class="ui fluid action input">
55
<input name="q" value="{{.Query}}" placeholder="{{.locale.Tr "explore.search"}}..." autofocus>
66
<select class="ui dropdown" name="type">
@@ -37,7 +37,7 @@
3737
</li>
3838
{{else}}
3939
{{if not .HasPackages}}
40-
<div class="empty center">
40+
<div class="empty list center">
4141
{{svg "octicon-package" 32}}
4242
<h2>{{.locale.Tr "packages.empty"}}</h2>
4343
{{if and .Repository .CanWritePackages}}

templates/package/shared/versionlist.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<div class="ui container">
1+
<div class="ui{{if .ContextUser.IsOrganization}} container{{end}}">
22
<p><a href="{{.PackageDescriptor.PackageWebLink}}">{{.PackageDescriptor.Package.Name}}</a> / <strong>{{.locale.Tr "packages.versions"}}</strong></p>
3-
<form class="ui form ignore-dirty">
3+
<form class="ui form ignore-dirty ">
44
<div class="ui fluid action input">
55
<input name="q" value="{{.Query}}" placeholder="{{.locale.Tr "explore.search"}}..." autofocus>
66
<select class="ui dropdown" name="sort">

templates/projects/list.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div role="main" aria-label="{{.Title}}" class="page-content repository projects">
2-
<div class="ui container">
2+
<div class="ui{{if .ContextUser.IsOrganization}} container{{end}}">
33
{{if .CanWriteProjects}}
44
<div class="navbar">
55
<div class="ui right">
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
{{if .ContextUser.IsOrganization}}
2+
{{with .ContextUser}}
3+
<div class="ui container">
4+
<div class="ui vertically grid head">
5+
<div class="column">
6+
<div class="ui header">
7+
{{avatar $.Context . 100}}
8+
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
9+
<span class="org-visibility">
10+
{{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
11+
{{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
12+
</span>
13+
</div>
14+
</div>
15+
</div>
16+
</div>
17+
{{end}}
18+
{{else}}
19+
<div class="ui card">
20+
<div id="profile-avatar" class="content gt-df">
21+
{{if eq .SignedUserID .ContextUser.ID}}
22+
<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{.locale.Tr "user.change_avatar"}}">
23+
{{/* the size doesn't take affect (and no need to take affect), image size(width) should be controlled by the parent container since this is not a flex layout*/}}
24+
{{avatar $.Context .ContextUser 256}}
25+
</a>
26+
{{else}}
27+
<span class="image">
28+
{{avatar $.Context .ContextUser 256}}
29+
</span>
30+
{{end}}
31+
</div>
32+
<div class="content gt-word-break profile-avatar-name">
33+
{{if .ContextUser.FullName}}<span class="header text center">{{.ContextUser.FullName}}</span>{{end}}
34+
<span class="username text center">{{.ContextUser.Name}}</span>
35+
{{if .EnableFeed}}
36+
<a href="{{.ContextUser.HomeLink}}.rss"><i class="ui text grey gt-ml-3" data-tooltip-content="{{.locale.Tr "rss_feed"}}">{{svg "octicon-rss" 18}}</i></a>
37+
{{end}}
38+
<div class="gt-mt-3">
39+
<a class="muted" href="{{.ContextUser.HomeLink}}?tab=followers">{{svg "octicon-person" 18 "gt-mr-2"}}{{.NumFollowers}} {{.locale.Tr "user.followers"}}</a> · <a class="muted" href="{{.ContextUser.HomeLink}}?tab=following">{{.NumFollowing}} {{.locale.Tr "user.following"}}</a>
40+
</div>
41+
</div>
42+
<div class="extra content gt-word-break">
43+
<ul>
44+
{{if .ContextUser.Location}}
45+
<li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li>
46+
{{end}}
47+
{{if (eq .SignedUserID .ContextUser.ID)}}
48+
<li>
49+
{{svg "octicon-mail"}}
50+
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
51+
<a href="{{AppSubUrl}}/user/settings#keep-email-private">
52+
{{if .ShowUserEmail}}
53+
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
54+
{{svg "octicon-unlock"}}
55+
</i>
56+
{{else}}
57+
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
58+
{{svg "octicon-lock"}}
59+
</i>
60+
{{end}}
61+
</a>
62+
</li>
63+
{{else}}
64+
{{if .ShowUserEmail}}
65+
<li>
66+
{{svg "octicon-mail"}}
67+
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
68+
</li>
69+
{{end}}
70+
{{end}}
71+
{{if .ContextUser.Website}}
72+
<li>
73+
{{svg "octicon-link"}}
74+
<a target="_blank" rel="noopener noreferrer me" href="{{.ContextUser.Website}}">{{.ContextUser.Website}}</a>
75+
</li>
76+
{{end}}
77+
{{if $.RenderedDescription}}
78+
<li>
79+
<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div>
80+
</li>
81+
{{end}}
82+
{{range .OpenIDs}}
83+
{{if .Show}}
84+
<li>
85+
{{svg "fontawesome-openid"}}
86+
<a target="_blank" rel="noopener noreferrer" href="{{.URI}}">{{.URI}}</a>
87+
</li>
88+
{{end}}
89+
{{end}}
90+
<li>{{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li>
91+
{{if and .Orgs .HasOrgsVisible}}
92+
<li>
93+
<ul class="user-orgs">
94+
{{range .Orgs}}
95+
{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
96+
<li>
97+
<a href="{{.HomeLink}}" data-tooltip-content="{{.Name}}">
98+
{{avatar $.Context .}}
99+
</a>
100+
</li>
101+
{{end}}
102+
{{end}}
103+
</ul>
104+
</li>
105+
{{end}}
106+
{{if .Badges}}
107+
<li>
108+
<ul class="user-badges">
109+
{{range .Badges}}
110+
<li>
111+
<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
112+
</li>
113+
{{end}}
114+
</ul>
115+
</li>
116+
{{end}}
117+
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
118+
<li class="follow">
119+
{{if $.IsFollowing}}
120+
<form method="post" action="{{.Link}}?action=unfollow&redirect_to={{$.Link}}">
121+
{{$.CsrfTokenHtml}}
122+
<button type="submit" class="ui basic red button">{{svg "octicon-person"}} {{.locale.Tr "user.unfollow"}}</button>
123+
</form>
124+
{{else}}
125+
<form method="post" action="{{.Link}}?action=follow&redirect_to={{$.Link}}">
126+
{{$.CsrfTokenHtml}}
127+
<button type="submit" class="ui basic green button">{{svg "octicon-person"}} {{.locale.Tr "user.follow"}}</button>
128+
</form>
129+
{{end}}
130+
</li>
131+
{{end}}
132+
</ul>
133+
</div>
134+
</div>
135+
{{end}}

templates/user/overview/header.tmpl

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,4 @@
1-
<!-- TODO: make template org and user can share -->
2-
{{if or (.IsPackagesPage) (.PageIsViewProjects)}}
3-
{{with .ContextUser}}
4-
<div class="ui container">
5-
<div class="ui vertically grid head">
6-
<div class="column">
7-
<div class="ui header">
8-
{{avatar $.Context . 100}}
9-
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
10-
<span class="org-visibility">
11-
{{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
12-
{{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
13-
</span>
14-
</div>
15-
</div>
16-
</div>
17-
</div>
18-
{{end}}
19-
{{end}}
20-
21-
<div class="ui tabs container">
1+
<div class="ui tabs{{if or (.ContextUser.IsOrganization) (not .ctxData.PageIsViewProjects)}} container{{end}}">
222
<div class="ui secondary stackable pointing menu">
233
{{if .ProfileReadme}}
244
<a class='{{if or (eq .TabName "overview") (and (eq .TabName "") (not .IsPackagesPage) (not .PageIsViewProjects))}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=overview">
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
{{template "base/head" .}}
2-
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
3-
{{template "user/overview/header" .}}
4-
{{template "package/shared/versionlist" .}}
5-
</div>
2+
{{if .ContextUser.IsOrganization}}
3+
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
4+
{{template "shared/user/profile_big_avatar" .}}
5+
{{template "user/overview/header" .}}
6+
{{template "package/shared/versionlist" .}}
7+
</div>
8+
{{else}}
9+
<div role="main" aria-label="{{.Title}}" class="page-content user profile packages">
10+
<div class="ui container">
11+
<div class="ui stackable grid">
12+
<div class="ui four wide column">
13+
{{template "shared/user/profile_big_avatar" .}}
14+
</div>
15+
<div class="ui twelve wide column">
16+
{{template "user/overview/header" .}}
17+
{{template "package/shared/versionlist" .}}
18+
</div>
19+
</div>
20+
</div>
21+
</div>
22+
{{end}}
623
{{template "base/footer" .}}

templates/user/overview/packages.tmpl

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
{{template "base/head" .}}
2-
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
3-
{{template "user/overview/header" .}}
4-
{{template "package/shared/list" .}}
5-
</div>
2+
{{if .ContextUser.IsOrganization}}
3+
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
4+
{{template "shared/user/profile_big_avatar" .}}
5+
{{template "user/overview/header" .}}
6+
{{template "package/shared/list" .}}
7+
</div>
8+
{{else}}
9+
<div role="main" aria-label="{{.Title}}" class="page-content user profile packages">
10+
<div class="ui container">
11+
<div class="ui stackable grid">
12+
<div class="ui four wide column">
13+
{{template "shared/user/profile_big_avatar" .}}
14+
</div>
15+
<div class="ui twelve wide column">
16+
{{template "user/overview/header" .}}
17+
{{template "package/shared/list" .}}
18+
</div>
19+
</div>
20+
</div>
21+
</div>
22+
{{end}}
623
{{template "base/footer" .}}
24+

0 commit comments

Comments
 (0)