diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index b3f6024b60606..6ac154e75fb10 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -11,13 +11,18 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/organization" project_model "code.gitea.io/gitea/models/project" attachment_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -41,15 +46,91 @@ func MustEnableProjects(ctx *context.Context) { // Projects renders the home page of projects func Projects(ctx *context.Context) { + // check view permissions + if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { + ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name)) + return + } + + // advertise feed via meta tag + ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink() + + // Show OpenID URIs + openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID) + if err != nil { + ctx.ServerError("GetUserOpenIDs", err) + return + } + + var isFollowing bool + if ctx.Doer != nil { + isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID) + } + + ctx.Data["ContextUser"] = ctx.ContextUser + ctx.Data["OpenIDs"] = openIDs + ctx.Data["IsFollowing"] = isFollowing + + if len(ctx.ContextUser.Description) != 0 { + content, err := markdown.RenderString(&markup.RenderContext{ + URLPrefix: ctx.Repo.RepoLink, + Metas: map[string]string{"mode": "document"}, + GitRepo: ctx.Repo.GitRepo, + Ctx: ctx, + }, ctx.ContextUser.Description) + if err != nil { + ctx.ServerError("RenderString", err) + return + } + ctx.Data["RenderedDescription"] = content + } + showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) + orgs, err := organization.FindOrgs(organization.FindOrgOptions{ + UserID: ctx.ContextUser.ID, + IncludePrivate: showPrivate, + }) + if err != nil { + ctx.ServerError("FindOrgs", err) + return + } + ctx.Data["Orgs"] = orgs + ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer) + + badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser) + if err != nil { + ctx.ServerError("GetUserBadges", err) + return + } + ctx.Data["Badges"] = badges + + pagingNum := setting.UI.User.RepoPagingNum + page := ctx.FormInt("page") + _, numFollowers, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ + PageSize: pagingNum, + Page: page, + }) + if err != nil { + ctx.ServerError("GetUserFollowers", err) + return + } + ctx.Data["NumFollowers"] = numFollowers + _, numFollowing, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ + PageSize: pagingNum, + Page: page, + }) + if err != nil { + ctx.ServerError("GetUserFollowing", err) + return + } + ctx.Data["NumFollowing"] = numFollowing + ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate + ctx.Data["EnableFeed"] = setting.Other.EnableFeed + ctx.Data["Title"] = ctx.Tr("repo.project_board") sortType := ctx.FormTrim("sort") isShowClosed := strings.ToLower(ctx.FormTrim("state")) == "closed" - page := ctx.FormInt("page") - if page <= 1 { - page = 1 - } var projectType project_model.Type if ctx.ContextUser.IsOrganization() { diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 81a26da827283..06d7074f0c940 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -4,6 +4,7 @@ package user import ( + "fmt" "net/http" "code.gitea.io/gitea/models/db" @@ -13,10 +14,13 @@ import ( "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/markup/markdown" alpine_module "code.gitea.io/gitea/modules/packages/alpine" debian_module "code.gitea.io/gitea/modules/packages/debian" "code.gitea.io/gitea/modules/setting" @@ -36,7 +40,86 @@ const ( // ListPackages displays a list of all packages of the context user func ListPackages(ctx *context.Context) { + // check view permissions + if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { + ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name)) + return + } + + // advertise feed via meta tag + ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink() + + // Show OpenID URIs + openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID) + if err != nil { + ctx.ServerError("GetUserOpenIDs", err) + return + } + + var isFollowing bool + if ctx.Doer != nil { + isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID) + } + + ctx.Data["ContextUser"] = ctx.ContextUser + ctx.Data["OpenIDs"] = openIDs + ctx.Data["IsFollowing"] = isFollowing + + if len(ctx.ContextUser.Description) != 0 { + content, err := markdown.RenderString(&markup.RenderContext{ + URLPrefix: ctx.Repo.RepoLink, + Metas: map[string]string{"mode": "document"}, + GitRepo: ctx.Repo.GitRepo, + Ctx: ctx, + }, ctx.ContextUser.Description) + if err != nil { + ctx.ServerError("RenderString", err) + return + } + ctx.Data["RenderedDescription"] = content + } + showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) + orgs, err := org_model.FindOrgs(org_model.FindOrgOptions{ + UserID: ctx.ContextUser.ID, + IncludePrivate: showPrivate, + }) + if err != nil { + ctx.ServerError("FindOrgs", err) + return + } + ctx.Data["Orgs"] = orgs + ctx.Data["HasOrgsVisible"] = org_model.HasOrgsVisible(orgs, ctx.Doer) + + badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser) + if err != nil { + ctx.ServerError("GetUserBadges", err) + return + } + ctx.Data["Badges"] = badges + + pagingNum := setting.UI.User.RepoPagingNum page := ctx.FormInt("page") + _, numFollowers, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ + PageSize: pagingNum, + Page: page, + }) + if err != nil { + ctx.ServerError("GetUserFollowers", err) + return + } + ctx.Data["NumFollowers"] = numFollowers + _, numFollowing, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ + PageSize: pagingNum, + Page: page, + }) + if err != nil { + ctx.ServerError("GetUserFollowing", err) + return + } + ctx.Data["NumFollowing"] = numFollowing + ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate + ctx.Data["EnableFeed"] = setting.Other.EnableFeed + if page <= 1 { page = 1 } diff --git a/templates/org/projects/list.tmpl b/templates/org/projects/list.tmpl index 1f113b28c84c9..46a7bfd58a259 100644 --- a/templates/org/projects/list.tmpl +++ b/templates/org/projects/list.tmpl @@ -1,6 +1,18 @@ {{template "base/head" .}} -
- {{template "user/overview/header" .}} - {{template "projects/list" .}} +
+ {{if .ContextUser.IsOrganization}} + {{template "user/overview/header" .}} + {{template "projects/list" .}} + {{else}} +
+
+ {{template "user/overview/big_profile_avatar" .}} +
+ {{template "user/overview/header_items" .}} + {{template "projects/overview_list" .}} +
+
+
+ {{end}}
{{template "base/footer" .}} diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index 707fbe357fbb8..010036ec46588 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -1,4 +1,4 @@ -
+
{{template "base/alert" .}}
diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index e9e86e5d5d585..78a7dd872e4cc 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -52,7 +52,7 @@
{{if and $.CanWriteProjects (not $.Repository.IsArchived)}} -
+
{{svg "octicon-pencil"}} {{$.locale.Tr "repo.issues.label_edit"}} {{if .IsClosed}} {{svg "octicon-check"}} {{$.locale.Tr "repo.projects.open"}} diff --git a/templates/projects/overview_list.tmpl b/templates/projects/overview_list.tmpl new file mode 100644 index 0000000000000..e8a666d7db4c1 --- /dev/null +++ b/templates/projects/overview_list.tmpl @@ -0,0 +1,89 @@ +
+
+ {{if .CanWriteProjects}} + +
+ {{end}} + + {{template "base/alert" .}} + + + +
+ {{range .Projects}} +
  • + {{svg .IconName}} {{.Title}} +
    + {{$closedDate:= TimeSinceUnix .ClosedDateUnix $.locale}} + {{if .IsClosed}} + {{svg "octicon-clock"}} {{$.locale.Tr "repo.milestones.closed" $closedDate | Safe}} + {{end}} + + {{svg "octicon-issue-opened" 16 "gt-mr-3"}} + {{$.locale.PrettyNumber .NumOpenIssues}} {{$.locale.Tr "repo.issues.open_title"}} + {{svg "octicon-check" 16 "gt-mr-3"}} + {{$.locale.PrettyNumber .NumClosedIssues}} {{$.locale.Tr "repo.issues.closed_title"}} + +
    + {{if and $.CanWriteProjects (not $.Repository.IsArchived)}} + + {{end}} + {{if .Description}} +
    + {{.RenderedContent|Str2html}} +
    + {{end}} +
  • + {{end}} + + {{template "base/paginate" .}} +
    +
    +
    + +{{if $.CanWriteProjects}} + +{{end}} diff --git a/templates/user/overview/big_profile_avatar.tmpl b/templates/user/overview/big_profile_avatar.tmpl new file mode 100644 index 0000000000000..1067858444234 --- /dev/null +++ b/templates/user/overview/big_profile_avatar.tmpl @@ -0,0 +1,118 @@ +
    +
    + +
    + {{if .ContextUser.FullName}}{{.ContextUser.FullName}}{{end}} + {{.ContextUser.Name}} + {{if .EnableFeed}} + {{svg "octicon-rss" 18}} + {{end}} + +
    +
    +
      + {{if .ContextUser.Location}} +
    • {{svg "octicon-location"}} {{.ContextUser.Location}}
    • + {{end}} + {{if (eq .SignedUserID .ContextUser.ID)}} +
    • + {{svg "octicon-mail"}} + {{.ContextUser.Email}} + + {{if .ShowUserEmail}} + + {{svg "octicon-unlock"}} + + {{else}} + + {{svg "octicon-lock"}} + + {{end}} + +
    • + {{else}} + {{if .ShowUserEmail}} +
    • + {{svg "octicon-mail"}} + {{.ContextUser.Email}} +
    • + {{end}} + {{end}} + {{if .ContextUser.Website}} +
    • + {{svg "octicon-link"}} + {{.ContextUser.Website}} +
    • + {{end}} + {{if $.RenderedDescription}} +
    • +
      {{$.RenderedDescription|Str2html}}
      +
    • + {{end}} + {{range .OpenIDs}} + {{if .Show}} +
    • + {{svg "fontawesome-openid"}} + {{.URI}} +
    • + {{end}} + {{end}} +
    • {{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}
    • + {{if and .Orgs .HasOrgsVisible}} +
    • +
        + {{range .Orgs}} + {{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}} +
      • + + {{avatar $.Context .}} + +
      • + {{end}} + {{end}} +
      +
    • + {{end}} + {{if .Badges}} +
    • +
        + {{range .Badges}} +
      • + {{.Description}} +
      • + {{end}} +
      +
    • + {{end}} + {{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}} + + {{else}} +
      + {{$.CsrfTokenHtml}} + +
      + {{end}} + + {{end}} +
    +
    +
    +
    diff --git a/templates/user/overview/header_items.tmpl b/templates/user/overview/header_items.tmpl new file mode 100644 index 0000000000000..22a2dd55bfe3b --- /dev/null +++ b/templates/user/overview/header_items.tmpl @@ -0,0 +1,72 @@ +
    + +
    diff --git a/templates/user/overview/packages.tmpl b/templates/user/overview/packages.tmpl index 8f8597c42d17b..b54735d986e57 100644 --- a/templates/user/overview/packages.tmpl +++ b/templates/user/overview/packages.tmpl @@ -1,6 +1,20 @@ {{template "base/head" .}} -
    - {{template "user/overview/header" .}} - {{template "package/shared/list" .}} +
    + {{if .ContextUser.IsOrganization}} + {{template "user/overview/header" .}} + {{template "package/shared/list" .}} + {{else}} +
    +
    + {{template "user/overview/big_profile_avatar" .}} +
    + {{template "user/overview/header_items" .}} +
    + {{template "package/shared/list" .}} +
    +
    +
    +
    + {{end}}
    {{template "base/footer" .}} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index b2b544a7ea1a9..2a09ba1f0afb3 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1202,6 +1202,10 @@ color: var(--color-red); } +.repository .milestone.project-options.list > .item .operate { + margin-top: -20px; +} + .repository .milestone.list > .item .operate { margin-top: -15px; } @@ -1922,6 +1926,11 @@ padding-bottom: 100px; } +.page-content .ui.ui.ui.container:not(.fluid) .empty { + padding-top: 70px; + padding-bottom: 100px; +} + .repository.packages .empty .svg { height: 48px; }