mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Fix inconsistent user profile layout across tabs (#25625)
Fix ::User Profile Page Project Tab Have Inconsistent Layout and Style Added the big_avator for consistency in the all header_items tabs. Fixes: #24871 > ### Description > in the user profile page the `Packages` and `Projects` tab have small icons for user but other tabs have bigger profile picture with user info: > > ### Screenshots > ### **For Packages And Projects:** >  > > ### **For Other Tabs:** >  > ## Before  ## After changes Project View <img width="1394" alt="image" src="https://github.com/go-gitea/gitea/assets/80308335/95d181d7-8e61-496d-9899-7b825c91ad56"> Packages View <img width="1378" alt="image" src="https://github.com/go-gitea/gitea/assets/80308335/7f5fd60f-6b18-4fa8-8c56-7b0d45d1a610"> ## Org view for projects page <img width="1385" alt="image" src="https://github.com/go-gitea/gitea/assets/80308335/6400dc89-a5ae-4f0a-831b-5b6efa020d89"> ## Org view for packages page <img width="1387" alt="image" src="https://github.com/go-gitea/gitea/assets/80308335/4e1e9ffe-1e4b-4334-8657-de11b5fd31d0"> --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Giteabot <teabot@gitea.io> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
		@@ -336,7 +336,7 @@ func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListO
 | 
			
		||||
 | 
			
		||||
// GetUserFollowing returns range of user's following.
 | 
			
		||||
func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) {
 | 
			
		||||
	sess := db.GetEngine(db.DefaultContext).
 | 
			
		||||
	sess := db.GetEngine(ctx).
 | 
			
		||||
		Select("`user`.*").
 | 
			
		||||
		Join("LEFT", "follow", "`user`.id=follow.follow_id").
 | 
			
		||||
		Where("follow.user_id=?", u.ID).
 | 
			
		||||
 
 | 
			
		||||
@@ -161,7 +161,6 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
 | 
			
		||||
	ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
 | 
			
		||||
	ctx.Data["IsProjectEnabled"] = true
 | 
			
		||||
	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 | 
			
		||||
	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 | 
			
		||||
	ctx.Data["IsPublicMember"] = func(uid int64) bool {
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@ func MustEnableProjects(ctx *context.Context) {
 | 
			
		||||
 | 
			
		||||
// Projects renders the home page of projects
 | 
			
		||||
func Projects(ctx *context.Context) {
 | 
			
		||||
	shared_user.PrepareContextForProfileBigAvatar(ctx)
 | 
			
		||||
	ctx.Data["Title"] = ctx.Tr("repo.project_board")
 | 
			
		||||
 | 
			
		||||
	sortType := ctx.FormTrim("sort")
 | 
			
		||||
 
 | 
			
		||||
@@ -4,35 +4,109 @@
 | 
			
		||||
package user
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"code.gitea.io/gitea/models/db"
 | 
			
		||||
	"code.gitea.io/gitea/models/organization"
 | 
			
		||||
	repo_model "code.gitea.io/gitea/models/repo"
 | 
			
		||||
	user_model "code.gitea.io/gitea/models/user"
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/markup"
 | 
			
		||||
	"code.gitea.io/gitea/modules/markup/markdown"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func RenderUserHeader(ctx *context.Context) {
 | 
			
		||||
	ctx.Data["IsProjectEnabled"] = true
 | 
			
		||||
// prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu)
 | 
			
		||||
// It is designed to be fast and safe to be called multiple times in one request
 | 
			
		||||
func prepareContextForCommonProfile(ctx *context.Context) {
 | 
			
		||||
	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 | 
			
		||||
	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 | 
			
		||||
	ctx.Data["ContextUser"] = ctx.ContextUser
 | 
			
		||||
	tab := ctx.FormString("tab")
 | 
			
		||||
	ctx.Data["TabName"] = tab
 | 
			
		||||
	repo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
 | 
			
		||||
	if err == nil && !repo.IsEmpty {
 | 
			
		||||
		gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
 | 
			
		||||
	ctx.Data["EnableFeed"] = setting.Other.EnableFeed
 | 
			
		||||
	ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrepareContextForProfileBigAvatar set the context for big avatar view on the profile page
 | 
			
		||||
func PrepareContextForProfileBigAvatar(ctx *context.Context) {
 | 
			
		||||
	prepareContextForCommonProfile(ctx)
 | 
			
		||||
 | 
			
		||||
	ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
 | 
			
		||||
	ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
 | 
			
		||||
 | 
			
		||||
	// Show OpenID URIs
 | 
			
		||||
	openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("GetUserOpenIDs", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["OpenIDs"] = openIDs
 | 
			
		||||
 | 
			
		||||
	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("OpenRepository", err)
 | 
			
		||||
			ctx.ServerError("RenderString", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		defer gitRepo.Close()
 | 
			
		||||
		commit, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.ServerError("GetBranchCommit", 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
 | 
			
		||||
 | 
			
		||||
	// in case the numbers are already provided by other functions, no need to query again (which is slow)
 | 
			
		||||
	if _, ok := ctx.Data["NumFollowers"]; !ok {
 | 
			
		||||
		_, ctx.Data["NumFollowers"], _ = user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{PageSize: 1, Page: 1})
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := ctx.Data["NumFollowing"]; !ok {
 | 
			
		||||
		_, ctx.Data["NumFollowing"], _ = user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{PageSize: 1, Page: 1})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func FindUserProfileReadme(ctx *context.Context) (profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
 | 
			
		||||
	profileDbRepo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
 | 
			
		||||
	if err == nil && !profileDbRepo.IsEmpty {
 | 
			
		||||
		if profileGitRepo, err = git.OpenRepository(ctx, profileDbRepo.RepoPath()); err != nil {
 | 
			
		||||
			log.Error("FindUserProfileReadme failed to OpenRepository: %v", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil {
 | 
			
		||||
				log.Error("FindUserProfileReadme failed to GetBranchCommit: %v", err)
 | 
			
		||||
			} else {
 | 
			
		||||
				profileReadmeBlob, _ = commit.GetBlobByPath("README.md")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		blob, err := commit.GetBlobByPath("README.md")
 | 
			
		||||
		if err == nil && blob != nil {
 | 
			
		||||
			ctx.Data["ProfileReadme"] = true
 | 
			
		||||
	}
 | 
			
		||||
	return profileGitRepo, profileReadmeBlob, func() {
 | 
			
		||||
		if profileGitRepo != nil {
 | 
			
		||||
			_ = profileGitRepo.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RenderUserHeader(ctx *context.Context) {
 | 
			
		||||
	prepareContextForCommonProfile(ctx)
 | 
			
		||||
 | 
			
		||||
	_, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx)
 | 
			
		||||
	defer profileClose()
 | 
			
		||||
	ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	code_indexer "code.gitea.io/gitea/modules/indexer/code"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	shared_user "code.gitea.io/gitea/routers/web/shared/user"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -23,8 +24,9 @@ func CodeSearch(ctx *context.Context) {
 | 
			
		||||
		ctx.Redirect(ctx.ContextUser.HomeLink())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	shared_user.PrepareContextForProfileBigAvatar(ctx)
 | 
			
		||||
	shared_user.RenderUserHeader(ctx)
 | 
			
		||||
 | 
			
		||||
	ctx.Data["IsProjectEnabled"] = true
 | 
			
		||||
	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 | 
			
		||||
	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 | 
			
		||||
	ctx.Data["Title"] = ctx.Tr("explore.code")
 | 
			
		||||
 
 | 
			
		||||
@@ -857,7 +857,7 @@ func UsernameSubRoute(ctx *context.Context) {
 | 
			
		||||
		context_service.UserAssignmentWeb()(ctx)
 | 
			
		||||
		if !ctx.Written() {
 | 
			
		||||
			ctx.Data["EnableFeed"] = setting.Other.EnableFeed
 | 
			
		||||
			Profile(ctx)
 | 
			
		||||
			OwnerProfile(ctx)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@ const (
 | 
			
		||||
 | 
			
		||||
// ListPackages displays a list of all packages of the context user
 | 
			
		||||
func ListPackages(ctx *context.Context) {
 | 
			
		||||
	shared_user.PrepareContextForProfileBigAvatar(ctx)
 | 
			
		||||
	page := ctx.FormInt("page")
 | 
			
		||||
	if page <= 1 {
 | 
			
		||||
		page = 1
 | 
			
		||||
@@ -259,6 +260,7 @@ func ViewPackageVersion(ctx *context.Context) {
 | 
			
		||||
 | 
			
		||||
// ListPackageVersions lists all versions of a package
 | 
			
		||||
func ListPackageVersions(ctx *context.Context) {
 | 
			
		||||
	shared_user.PrepareContextForProfileBigAvatar(ctx)
 | 
			
		||||
	p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if err == packages_model.ErrPackageNotExist {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,22 +11,22 @@ import (
 | 
			
		||||
 | 
			
		||||
	activities_model "code.gitea.io/gitea/models/activities"
 | 
			
		||||
	"code.gitea.io/gitea/models/db"
 | 
			
		||||
	"code.gitea.io/gitea/models/organization"
 | 
			
		||||
	project_model "code.gitea.io/gitea/models/project"
 | 
			
		||||
	repo_model "code.gitea.io/gitea/models/repo"
 | 
			
		||||
	user_model "code.gitea.io/gitea/models/user"
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"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/routers/web/feed"
 | 
			
		||||
	"code.gitea.io/gitea/routers/web/org"
 | 
			
		||||
	shared_user "code.gitea.io/gitea/routers/web/shared/user"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Profile render user's profile page
 | 
			
		||||
func Profile(ctx *context.Context) {
 | 
			
		||||
// OwnerProfile render profile page for a user or a organization (aka, repo owner)
 | 
			
		||||
func OwnerProfile(ctx *context.Context) {
 | 
			
		||||
	if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
 | 
			
		||||
		feed.ShowUserFeedRSS(ctx)
 | 
			
		||||
		return
 | 
			
		||||
@@ -38,36 +38,22 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
 | 
			
		||||
	if ctx.ContextUser.IsOrganization() {
 | 
			
		||||
		org.Home(ctx)
 | 
			
		||||
		return
 | 
			
		||||
	} else {
 | 
			
		||||
		userProfile(ctx)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func userProfile(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["Title"] = ctx.ContextUser.DisplayName()
 | 
			
		||||
	ctx.Data["PageIsUserProfile"] = true
 | 
			
		||||
	ctx.Data["ContextUser"] = ctx.ContextUser
 | 
			
		||||
	ctx.Data["OpenIDs"] = openIDs
 | 
			
		||||
	ctx.Data["IsFollowing"] = isFollowing
 | 
			
		||||
 | 
			
		||||
	// prepare heatmap data
 | 
			
		||||
	if setting.Service.EnableUserHeatmap {
 | 
			
		||||
		data, err := activities_model.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -78,75 +64,28 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
		ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
 | 
			
		||||
	if err == nil && !repo.IsEmpty {
 | 
			
		||||
		gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.ServerError("OpenRepository", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		defer gitRepo.Close()
 | 
			
		||||
		commit, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.ServerError("GetBranchCommit", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		blob, err := commit.GetBlobByPath("README.md")
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			bytes, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.ServerError("GetBlobContent", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			profileContent, err := markdown.RenderString(&markup.RenderContext{
 | 
			
		||||
				Ctx:     ctx,
 | 
			
		||||
				GitRepo: gitRepo,
 | 
			
		||||
			}, bytes)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.ServerError("RenderString", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Data["ProfileReadme"] = profileContent
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx)
 | 
			
		||||
	defer profileClose()
 | 
			
		||||
 | 
			
		||||
	showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
 | 
			
		||||
	prepareUserProfileTabData(ctx, showPrivate, profileGitRepo, profileReadmeBlob)
 | 
			
		||||
	// call PrepareContextForProfileBigAvatar later to avoid re-querying the NumFollowers & NumFollowing
 | 
			
		||||
	shared_user.PrepareContextForProfileBigAvatar(ctx)
 | 
			
		||||
	ctx.HTML(http.StatusOK, tplProfile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGitRepo *git.Repository, profileReadme *git.Blob) {
 | 
			
		||||
	// if there is a profile readme, default to "overview" page, otherwise, default to "repositories" page
 | 
			
		||||
	tab := ctx.FormString("tab")
 | 
			
		||||
	if tab == "" {
 | 
			
		||||
		if profileReadme != nil {
 | 
			
		||||
			tab = "overview"
 | 
			
		||||
		} else {
 | 
			
		||||
			tab = "repositories"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["TabName"] = tab
 | 
			
		||||
	ctx.Data["HasProfileReadme"] = profileReadme != nil
 | 
			
		||||
 | 
			
		||||
	page := ctx.FormInt("page")
 | 
			
		||||
	if page <= 0 {
 | 
			
		||||
@@ -154,12 +93,7 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pagingNum := setting.UI.User.RepoPagingNum
 | 
			
		||||
	if tab == "activity" {
 | 
			
		||||
		pagingNum = setting.UI.FeedPagingNum
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	topicOnly := ctx.FormBool("topic")
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		repos   []*repo_model.Repository
 | 
			
		||||
		count   int64
 | 
			
		||||
@@ -228,6 +162,7 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
		total = int(count)
 | 
			
		||||
	case "activity":
 | 
			
		||||
		date := ctx.FormString("date")
 | 
			
		||||
		pagingNum = setting.UI.FeedPagingNum
 | 
			
		||||
		items, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
 | 
			
		||||
			RequestedUser:   ctx.ContextUser,
 | 
			
		||||
			Actor:           ctx.Doer,
 | 
			
		||||
@@ -271,16 +206,6 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		total = int(count)
 | 
			
		||||
	case "projects":
 | 
			
		||||
		ctx.Data["OpenProjects"], _, err = project_model.FindProjects(ctx, project_model.SearchOptions{
 | 
			
		||||
			Page:     -1,
 | 
			
		||||
			IsClosed: util.OptionalBoolFalse,
 | 
			
		||||
			Type:     project_model.TypeIndividual,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.ServerError("GetProjects", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	case "watching":
 | 
			
		||||
		repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 | 
			
		||||
			ListOptions: db.ListOptions{
 | 
			
		||||
@@ -303,7 +228,17 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		total = int(count)
 | 
			
		||||
	default:
 | 
			
		||||
	case "overview":
 | 
			
		||||
		if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
 | 
			
		||||
			log.Error("failed to GetBlobContent: %v", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			if profileContent, err := markdown.RenderString(&markup.RenderContext{Ctx: ctx, GitRepo: profileGitRepo}, bytes); err != nil {
 | 
			
		||||
				log.Error("failed to RenderString: %v", err)
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.Data["ProfileReadme"] = profileContent
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	default: // default to "repositories"
 | 
			
		||||
		repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
 | 
			
		||||
			ListOptions: db.ListOptions{
 | 
			
		||||
				PageSize: pagingNum,
 | 
			
		||||
@@ -339,13 +274,6 @@ func Profile(ctx *context.Context) {
 | 
			
		||||
		pager.AddParam(ctx, "date", "Date")
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["Page"] = pager
 | 
			
		||||
	ctx.Data["IsProjectEnabled"] = true
 | 
			
		||||
	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 | 
			
		||||
	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 | 
			
		||||
 | 
			
		||||
	ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
 | 
			
		||||
 | 
			
		||||
	ctx.HTML(http.StatusOK, tplProfile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Action response for follow/unfollow user request
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								templates/code/searchcombo.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								templates/code/searchcombo.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
{{template "code/searchform" .}}
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<div class="ui user list">
 | 
			
		||||
	{{if .CodeIndexerUnavailable}}
 | 
			
		||||
		<div class="ui error message">
 | 
			
		||||
			<p>{{$.locale.Tr "explore.code_search_unavailable"}}</p>
 | 
			
		||||
		</div>
 | 
			
		||||
	{{else if .SearchResults}}
 | 
			
		||||
		<h3>
 | 
			
		||||
			{{.locale.Tr "explore.code_search_results" (.Keyword|Escape) | Str2html}}
 | 
			
		||||
		</h3>
 | 
			
		||||
		{{template "code/searchresults" .}}
 | 
			
		||||
	{{else if .Keyword}}
 | 
			
		||||
		<div>{{$.locale.Tr "explore.code_no_results"}}</div>
 | 
			
		||||
	{{end}}
 | 
			
		||||
</div>
 | 
			
		||||
{{template "base/paginate" .}}
 | 
			
		||||
@@ -2,24 +2,7 @@
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content explore users">
 | 
			
		||||
	{{template "explore/navbar" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		{{template "code/searchform" .}}
 | 
			
		||||
		<div class="divider"></div>
 | 
			
		||||
		<div class="ui user list">
 | 
			
		||||
			{{if .CodeIndexerUnavailable}}
 | 
			
		||||
				<div class="ui error message">
 | 
			
		||||
					<p>{{$.locale.Tr "explore.code_search_unavailable"}}</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			{{else if .SearchResults}}
 | 
			
		||||
				<h3>
 | 
			
		||||
					{{.locale.Tr "explore.code_search_results" (.Keyword|Escape) | Str2html}}
 | 
			
		||||
				</h3>
 | 
			
		||||
				{{template "code/searchresults" .}}
 | 
			
		||||
			{{else if .Keyword}}
 | 
			
		||||
				<div>{{$.locale.Tr "explore.code_no_results"}}</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		{{template "base/paginate" .}}
 | 
			
		||||
		{{template "code/searchcombo" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<div class="ui tabs container">
 | 
			
		||||
<div class="ui container">
 | 
			
		||||
	<div class="ui secondary stackable pointing menu">
 | 
			
		||||
		<a class="{{if .PageIsViewRepositories}}active {{end}}item" href="{{$.Org.HomeLink}}">
 | 
			
		||||
			{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
				<div class="ui small label">{{.ContextUser.NumRepos}}</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		</a>
 | 
			
		||||
		{{if and .IsProjectEnabled .CanReadProjects}}
 | 
			
		||||
		{{if .CanReadProjects}}
 | 
			
		||||
		<a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects">
 | 
			
		||||
			{{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}}
 | 
			
		||||
		</a>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,27 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "projects/list" .}}
 | 
			
		||||
</div>
 | 
			
		||||
{{if .ContextUser.IsOrganization}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
		{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
		{{template "user/overview/header" .}}
 | 
			
		||||
		{{template "projects/list" .}}
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{else}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content user profile">
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
			<div class="ui stackable grid">
 | 
			
		||||
				<div class="ui four wide column">
 | 
			
		||||
					{{template "shared/user/profile_big_avatar" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="ui twelve wide column">
 | 
			
		||||
				<div class="gt-mb-4">
 | 
			
		||||
					{{template "user/overview/header" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
				{{template "projects/list" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{end}}
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content organization projects edit-project new">
 | 
			
		||||
	{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "projects/new" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
	{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "projects/view" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository settings options">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		{{template "user/overview/header" .}}
 | 
			
		||||
		{{template "base/alert" .}}
 | 
			
		||||
		<p><a href="{{.PackageDescriptor.FullWebLink}}">{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</a> / <strong>{{.locale.Tr "repo.settings"}}</strong></p>
 | 
			
		||||
		<h4 class="ui top attached header">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
<div class="ui container">
 | 
			
		||||
	{{template "base/alert" .}}
 | 
			
		||||
	<form class="ui form ignore-dirty">
 | 
			
		||||
		<div class="ui fluid action input">
 | 
			
		||||
@@ -37,7 +36,7 @@
 | 
			
		||||
			</li>
 | 
			
		||||
		{{else}}
 | 
			
		||||
			{{if not .HasPackages}}
 | 
			
		||||
				<div class="empty center">
 | 
			
		||||
				<div class="gt-pt-5 empty center">
 | 
			
		||||
					{{svg "octicon-package" 48}}
 | 
			
		||||
					<h2>{{.locale.Tr "packages.empty"}}</h2>
 | 
			
		||||
					{{if and .Repository .CanWritePackages}}
 | 
			
		||||
@@ -52,4 +51,3 @@
 | 
			
		||||
		{{end}}
 | 
			
		||||
		{{template "base/paginate" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
<div class="ui container">
 | 
			
		||||
	<p><a href="{{.PackageDescriptor.PackageWebLink}}">{{.PackageDescriptor.Package.Name}}</a> / <strong>{{.locale.Tr "packages.versions"}}</strong></p>
 | 
			
		||||
	<form class="ui form ignore-dirty">
 | 
			
		||||
		<div class="ui fluid action input">
 | 
			
		||||
@@ -36,4 +35,3 @@
 | 
			
		||||
		{{end}}
 | 
			
		||||
		{{template "base/paginate" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository view issue packages">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		{{template "user/overview/header" .}}
 | 
			
		||||
		<div class="issue-title-header">
 | 
			
		||||
			<div class="issue-title">
 | 
			
		||||
				<h1>{{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}})</h1>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository projects">
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		{{if .CanWriteProjects}}
 | 
			
		||||
			<div class="navbar">
 | 
			
		||||
				<div class="ui right">
 | 
			
		||||
					<a class="ui small green button" href="{{$.Link}}/new">{{.locale.Tr "repo.projects.new"}}</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			<div class="gt-tr">
 | 
			
		||||
				<a class="ui small green button" href="{{$.Link}}/new">{{.locale.Tr "repo.projects.new"}}</a>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="divider"></div>
 | 
			
		||||
		{{end}}
 | 
			
		||||
@@ -75,8 +71,6 @@
 | 
			
		||||
 | 
			
		||||
			{{template "base/paginate" .}}
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{{if $.CanWriteProjects}}
 | 
			
		||||
<div class="ui g-modal-confirm delete modal">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
<div class="ui container">
 | 
			
		||||
	<h2 class="ui dividing header">
 | 
			
		||||
		{{if .PageIsEditProjects}}
 | 
			
		||||
		{{.locale.Tr "repo.projects.edit"}}
 | 
			
		||||
@@ -55,7 +54,6 @@
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
			<div class="divider"></div>
 | 
			
		||||
			<div class="ui left">
 | 
			
		||||
				<a class="ui cancel button" href="{{$.CancelLink}}">
 | 
			
		||||
@@ -65,6 +63,4 @@
 | 
			
		||||
					{{if .PageIsEditProjects}}{{.locale.Tr "repo.projects.modify"}}{{else}}{{.locale.Tr "repo.projects.create"}}{{end}}
 | 
			
		||||
				</button>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</form>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
	{{template "repo/header" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
	{{template "package/shared/list" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository projects edit-project new milestone">
 | 
			
		||||
	{{template "repo/header" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
	{{template "projects/new" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								templates/shared/user/org_profile_avatar.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								templates/shared/user/org_profile_avatar.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
{{with .ContextUser}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		<div class="ui vertically grid head">
 | 
			
		||||
			<div class="column">
 | 
			
		||||
				<div class="ui header">
 | 
			
		||||
					{{avatar $.Context . 100}}
 | 
			
		||||
					<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
 | 
			
		||||
					<span class="org-visibility">
 | 
			
		||||
						{{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
 | 
			
		||||
						{{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
 | 
			
		||||
					</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{end}}
 | 
			
		||||
							
								
								
									
										116
									
								
								templates/shared/user/profile_big_avatar.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								templates/shared/user/profile_big_avatar.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
<div class="ui card">
 | 
			
		||||
	<div id="profile-avatar" class="content gt-df">
 | 
			
		||||
	{{if eq .SignedUserID .ContextUser.ID}}
 | 
			
		||||
		<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{.locale.Tr "user.change_avatar"}}">
 | 
			
		||||
			{{/* 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*/}}
 | 
			
		||||
			{{avatar $.Context .ContextUser 256}}
 | 
			
		||||
		</a>
 | 
			
		||||
	{{else}}
 | 
			
		||||
		<span class="image">
 | 
			
		||||
			{{avatar $.Context .ContextUser 256}}
 | 
			
		||||
		</span>
 | 
			
		||||
	{{end}}
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="content gt-word-break profile-avatar-name">
 | 
			
		||||
		{{if .ContextUser.FullName}}<span class="header text center">{{.ContextUser.FullName}}</span>{{end}}
 | 
			
		||||
		<span class="username text center">{{.ContextUser.Name}}</span>
 | 
			
		||||
		{{if .EnableFeed}}
 | 
			
		||||
			<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>
 | 
			
		||||
		{{end}}
 | 
			
		||||
		<div class="gt-mt-3">
 | 
			
		||||
			<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>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="extra content gt-word-break">
 | 
			
		||||
		<ul>
 | 
			
		||||
			{{if .ContextUser.Location}}
 | 
			
		||||
				<li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li>
 | 
			
		||||
			{{end}}
 | 
			
		||||
			{{if (eq .SignedUserID .ContextUser.ID)}}
 | 
			
		||||
				<li>
 | 
			
		||||
					{{svg "octicon-mail"}}
 | 
			
		||||
					<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
 | 
			
		||||
					<a href="{{AppSubUrl}}/user/settings#keep-email-private">
 | 
			
		||||
						{{if .ShowUserEmail}}
 | 
			
		||||
							<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
 | 
			
		||||
								{{svg "octicon-unlock"}}
 | 
			
		||||
							</i>
 | 
			
		||||
						{{else}}
 | 
			
		||||
							<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
 | 
			
		||||
								{{svg "octicon-lock"}}
 | 
			
		||||
							</i>
 | 
			
		||||
						{{end}}
 | 
			
		||||
					</a>
 | 
			
		||||
				</li>
 | 
			
		||||
			{{else}}
 | 
			
		||||
				{{if .ShowUserEmail}}
 | 
			
		||||
					<li>
 | 
			
		||||
						{{svg "octicon-mail"}}
 | 
			
		||||
						<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
 | 
			
		||||
					</li>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			{{end}}
 | 
			
		||||
			{{if .ContextUser.Website}}
 | 
			
		||||
				<li>
 | 
			
		||||
					{{svg "octicon-link"}}
 | 
			
		||||
					<a target="_blank" rel="noopener noreferrer me" href="{{.ContextUser.Website}}">{{.ContextUser.Website}}</a>
 | 
			
		||||
				</li>
 | 
			
		||||
			{{end}}
 | 
			
		||||
			{{if $.RenderedDescription}}
 | 
			
		||||
				<li>
 | 
			
		||||
					<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div>
 | 
			
		||||
				</li>
 | 
			
		||||
			{{end}}
 | 
			
		||||
			{{range .OpenIDs}}
 | 
			
		||||
				{{if .Show}}
 | 
			
		||||
					<li>
 | 
			
		||||
						{{svg "fontawesome-openid"}}
 | 
			
		||||
						<a target="_blank" rel="noopener noreferrer" href="{{.URI}}">{{.URI}}</a>
 | 
			
		||||
					</li>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			{{end}}
 | 
			
		||||
			<li>{{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li>
 | 
			
		||||
			{{if and .Orgs .HasOrgsVisible}}
 | 
			
		||||
			<li>
 | 
			
		||||
				<ul class="user-orgs">
 | 
			
		||||
				{{range .Orgs}}
 | 
			
		||||
					{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
 | 
			
		||||
					<li>
 | 
			
		||||
						<a href="{{.HomeLink}}" data-tooltip-content="{{.Name}}">
 | 
			
		||||
							{{avatar $.Context .}}
 | 
			
		||||
						</a>
 | 
			
		||||
					</li>
 | 
			
		||||
					{{end}}
 | 
			
		||||
				{{end}}
 | 
			
		||||
				</ul>
 | 
			
		||||
			</li>
 | 
			
		||||
			{{end}}
 | 
			
		||||
			{{if .Badges}}
 | 
			
		||||
			<li>
 | 
			
		||||
				<ul class="user-badges">
 | 
			
		||||
				{{range .Badges}}
 | 
			
		||||
					<li>
 | 
			
		||||
						<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
 | 
			
		||||
					</li>
 | 
			
		||||
				{{end}}
 | 
			
		||||
				</ul>
 | 
			
		||||
			</li>
 | 
			
		||||
			{{end}}
 | 
			
		||||
			{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
 | 
			
		||||
			<li class="follow">
 | 
			
		||||
				{{if $.IsFollowing}}
 | 
			
		||||
					<form method="post" action="{{.Link}}?action=unfollow&redirect_to={{$.Link}}">
 | 
			
		||||
						{{$.CsrfTokenHtml}}
 | 
			
		||||
						<button type="submit" class="ui basic red button">{{svg "octicon-person"}} {{.locale.Tr "user.unfollow"}}</button>
 | 
			
		||||
					</form>
 | 
			
		||||
				{{else}}
 | 
			
		||||
					<form method="post" action="{{.Link}}?action=follow&redirect_to={{$.Link}}">
 | 
			
		||||
						{{$.CsrfTokenHtml}}
 | 
			
		||||
						<button type="submit" class="ui basic green button">{{svg "octicon-person"}} {{.locale.Tr "user.follow"}}</button>
 | 
			
		||||
					</form>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</li>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		</ul>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,25 +1,25 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository code-search">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		{{template "code/searchform" .}}
 | 
			
		||||
		<div class="divider"></div>
 | 
			
		||||
		<div class="ui user list">
 | 
			
		||||
			{{if .CodeIndexerUnavailable}}
 | 
			
		||||
				<div class="ui error message">
 | 
			
		||||
					<p>{{$.locale.Tr "explore.code_search_unavailable"}}</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			{{else if .SearchResults}}
 | 
			
		||||
				<h3>
 | 
			
		||||
					{{.locale.Tr "explore.code_search_results" (.Keyword|Escape) | Str2html}}
 | 
			
		||||
				</h3>
 | 
			
		||||
				{{template "code/searchresults" .}}
 | 
			
		||||
			{{else if .Keyword}}
 | 
			
		||||
				<div>{{$.locale.Tr "explore.code_no_results"}}</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
{{if .ContextUser.IsOrganization}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content repository">
 | 
			
		||||
		{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
			{{template "user/overview/header" .}}
 | 
			
		||||
			{{template "code/searchcombo" .}}
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		{{template "base/paginate" .}}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{else}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content user profile">
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
			<div class="ui stackable grid">
 | 
			
		||||
				<div class="ui four wide column">
 | 
			
		||||
					{{template "shared/user/profile_big_avatar" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="ui twelve wide column">
 | 
			
		||||
					{{template "user/overview/header" .}}
 | 
			
		||||
					{{template "code/searchcombo" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{end}}
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,92 +1,69 @@
 | 
			
		||||
<!-- TODO: make template org and user can share -->
 | 
			
		||||
{{if or (.IsPackagesPage) (.PageIsViewProjects)}}
 | 
			
		||||
	{{with .ContextUser}}
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
		<div class="ui vertically grid head">
 | 
			
		||||
			<div class="column">
 | 
			
		||||
				<div class="ui header">
 | 
			
		||||
					{{avatar $.Context . 100}}
 | 
			
		||||
					<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
 | 
			
		||||
					<span class="org-visibility">
 | 
			
		||||
						{{if .Visibility.IsLimited}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.limited_shortname"}}</div>{{end}}
 | 
			
		||||
						{{if .Visibility.IsPrivate}}<div class="ui medium basic horizontal label">{{$.locale.Tr "org.settings.visibility.private_shortname"}}</div>{{end}}
 | 
			
		||||
					</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
<div class="ui secondary stackable pointing menu">
 | 
			
		||||
	{{if .HasProfileReadme}}
 | 
			
		||||
	<a class='{{if eq .TabName "overview"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=overview">
 | 
			
		||||
		{{svg "octicon-info"}} {{.locale.Tr "user.overview"}}
 | 
			
		||||
	</a>
 | 
			
		||||
	{{end}}
 | 
			
		||||
	<a class="{{if eq .TabName "repositories"}}active {{end}} item" href="{{.ContextUser.HomeLink}}?tab=repositories">
 | 
			
		||||
		{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
 | 
			
		||||
		{{if .ContextUser.NumRepos}}
 | 
			
		||||
			<div class="ui small label">{{.ContextUser.NumRepos}}</div>
 | 
			
		||||
		{{end}}
 | 
			
		||||
	</a>
 | 
			
		||||
	{{if or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects)}}
 | 
			
		||||
	<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
 | 
			
		||||
		{{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}}
 | 
			
		||||
	</a>
 | 
			
		||||
	{{end}}
 | 
			
		||||
	{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
 | 
			
		||||
		<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
 | 
			
		||||
			{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
 | 
			
		||||
		</a>
 | 
			
		||||
	{{end}}
 | 
			
		||||
	{{if and .IsRepoIndexerEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadCode))}}
 | 
			
		||||
		<a href="{{.ContextUser.HomeLink}}/-/code" class="{{if .IsCodePage}}active {{end}}item">
 | 
			
		||||
			{{svg "octicon-code"}} {{.locale.Tr "user.code"}}
 | 
			
		||||
		</a>
 | 
			
		||||
	{{end}}
 | 
			
		||||
{{end}}
 | 
			
		||||
 | 
			
		||||
<div class="ui tabs container">
 | 
			
		||||
	<div class="ui secondary stackable pointing menu">
 | 
			
		||||
		{{if .ProfileReadme}}
 | 
			
		||||
		<a class='{{if or (eq .TabName "overview") (and (eq .TabName "") (not .IsPackagesPage) (not .PageIsViewProjects))}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=overview">
 | 
			
		||||
							{{svg "octicon-info"}} {{.locale.Tr "user.overview"}}
 | 
			
		||||
						</a>
 | 
			
		||||
		{{end}}
 | 
			
		||||
		<a class="{{if or (eq .TabName "repositories") (and (eq .TabName "") (not .IsPackagesPage) (not .PageIsViewProjects) (not .ProfileReadme))}}active {{end}} item" href="{{.ContextUser.HomeLink}}?tab=repositories">
 | 
			
		||||
			{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
 | 
			
		||||
			{{if .ContextUser.NumRepos}}
 | 
			
		||||
				<div class="ui small label">{{.ContextUser.NumRepos}}</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		</a>
 | 
			
		||||
		{{if and .IsProjectEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects))}}
 | 
			
		||||
		<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
 | 
			
		||||
			{{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}}
 | 
			
		||||
		</a>
 | 
			
		||||
		{{end}}
 | 
			
		||||
		{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
 | 
			
		||||
			<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
 | 
			
		||||
				{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
 | 
			
		||||
	{{if .ContextUser.IsOrganization}}
 | 
			
		||||
		{{if .IsOrganizationMember}}
 | 
			
		||||
			<a class="item" href="{{$.OrgLink}}/members">
 | 
			
		||||
				{{svg "octicon-person"}} {{$.locale.Tr "org.members"}}
 | 
			
		||||
				{{if .NumMembers}}
 | 
			
		||||
					<div class="ui small label">{{.NumMembers}}</div>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</a>
 | 
			
		||||
		{{end}}
 | 
			
		||||
		{{if and .IsRepoIndexerEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadCode))}}
 | 
			
		||||
			<a href="{{.ContextUser.HomeLink}}/-/code" class="{{if .IsCodePage}}active {{end}}item">
 | 
			
		||||
				{{svg "octicon-code"}} {{.locale.Tr "user.code"}}
 | 
			
		||||
			<a class="item" href="{{$.OrgLink}}/teams">
 | 
			
		||||
				{{svg "octicon-people"}} {{$.locale.Tr "org.teams"}}
 | 
			
		||||
				{{if .NumTeams}}
 | 
			
		||||
					<div class="ui small label">{{.NumTeams}}</div>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</a>
 | 
			
		||||
		{{end}}
 | 
			
		||||
 | 
			
		||||
		{{if .ContextUser.IsOrganization}}
 | 
			
		||||
			{{if .IsOrganizationMember}}
 | 
			
		||||
				<a class="item" href="{{$.OrgLink}}/members">
 | 
			
		||||
					{{svg "octicon-person"}} {{$.locale.Tr "org.members"}}
 | 
			
		||||
					{{if .NumMembers}}
 | 
			
		||||
						<div class="ui small label">{{.NumMembers}}</div>
 | 
			
		||||
					{{end}}
 | 
			
		||||
		{{if .IsOrganizationOwner}}
 | 
			
		||||
			<div class="right menu">
 | 
			
		||||
				<a class="item" href="{{.OrgLink}}/settings">
 | 
			
		||||
				{{svg "octicon-tools"}} {{.locale.Tr "repo.settings"}}
 | 
			
		||||
				</a>
 | 
			
		||||
				<a class="item" href="{{$.OrgLink}}/teams">
 | 
			
		||||
					{{svg "octicon-people"}} {{$.locale.Tr "org.teams"}}
 | 
			
		||||
					{{if .NumTeams}}
 | 
			
		||||
						<div class="ui small label">{{.NumTeams}}</div>
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</a>
 | 
			
		||||
			{{end}}
 | 
			
		||||
 | 
			
		||||
			{{if .IsOrganizationOwner}}
 | 
			
		||||
				<div class="right menu">
 | 
			
		||||
					<a class="item" href="{{.OrgLink}}/settings">
 | 
			
		||||
					{{svg "octicon-tools"}} {{.locale.Tr "repo.settings"}}
 | 
			
		||||
					</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
		{{end}}
 | 
			
		||||
	{{else}}
 | 
			
		||||
		<a class='{{if eq .TabName "activity"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=activity">
 | 
			
		||||
			{{svg "octicon-rss"}} {{.locale.Tr "user.activity"}}
 | 
			
		||||
		</a>
 | 
			
		||||
		{{if not .DisableStars}}
 | 
			
		||||
			<a class='{{if eq .TabName "stars"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=stars">
 | 
			
		||||
				{{svg "octicon-star"}} {{.locale.Tr "user.starred"}}
 | 
			
		||||
				{{if .ContextUser.NumStars}}
 | 
			
		||||
					<div class="ui small label">{{.ContextUser.NumStars}}</div>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</a>
 | 
			
		||||
		{{else}}
 | 
			
		||||
			<a class='{{if eq .TabName "activity"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=activity">
 | 
			
		||||
				{{svg "octicon-rss"}} {{.locale.Tr "user.activity"}}
 | 
			
		||||
			<a class='{{if eq .TabName "watching"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=watching">
 | 
			
		||||
				{{svg "octicon-eye"}} {{.locale.Tr "user.watched"}}
 | 
			
		||||
			</a>
 | 
			
		||||
			{{if not .DisableStars}}
 | 
			
		||||
				<a class='{{if eq .TabName "stars"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=stars">
 | 
			
		||||
					{{svg "octicon-star"}} {{.locale.Tr "user.starred"}}
 | 
			
		||||
					{{if .ContextUser.NumStars}}
 | 
			
		||||
						<div class="ui small label">{{.ContextUser.NumStars}}</div>
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</a>
 | 
			
		||||
			{{else}}
 | 
			
		||||
				<a class='{{if eq .TabName "watching"}}active {{end}}item' href="{{.ContextUser.HomeLink}}?tab=watching">
 | 
			
		||||
					{{svg "octicon-eye"}} {{.locale.Tr "user.watched"}}
 | 
			
		||||
				</a>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		{{end}}
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
	{{end}}
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,27 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "package/shared/versionlist" .}}
 | 
			
		||||
{{if .ContextUser.IsOrganization}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
		{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
		{{template "user/overview/header" .}}
 | 
			
		||||
		{{template "package/shared/versionlist" .}}
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{else}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content user profile packages">
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		<div class="ui stackable grid">
 | 
			
		||||
			<div class="ui four wide column">
 | 
			
		||||
				{{template "shared/user/profile_big_avatar" .}}
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="ui twelve wide column">
 | 
			
		||||
				<div class="gt-mb-4">
 | 
			
		||||
					{{template "user/overview/header" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
				{{template "package/shared/versionlist" .}}
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
{{end}}
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,27 @@
 | 
			
		||||
{{template "base/head" .}}
 | 
			
		||||
<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
	{{template "user/overview/header" .}}
 | 
			
		||||
	{{template "package/shared/list" .}}
 | 
			
		||||
</div>
 | 
			
		||||
{{if .ContextUser.IsOrganization}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content repository packages">
 | 
			
		||||
		{{template "shared/user/org_profile_avatar" .}}
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
		{{template "user/overview/header" .}}
 | 
			
		||||
		{{template "package/shared/list" .}}
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{else}}
 | 
			
		||||
	<div role="main" aria-label="{{.Title}}" class="page-content user profile packages">
 | 
			
		||||
		<div class="ui container">
 | 
			
		||||
			<div class="ui stackable grid">
 | 
			
		||||
				<div class="ui four wide column">
 | 
			
		||||
					{{template "shared/user/profile_big_avatar" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="ui twelve wide column">
 | 
			
		||||
					<div class="gt-mb-4">
 | 
			
		||||
						{{template "user/overview/header" .}}
 | 
			
		||||
					</div>
 | 
			
		||||
					{{template "package/shared/list" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
{{end}}
 | 
			
		||||
{{template "base/footer" .}}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,125 +3,10 @@
 | 
			
		||||
	<div class="ui container">
 | 
			
		||||
		<div class="ui stackable grid">
 | 
			
		||||
			<div class="ui four wide column">
 | 
			
		||||
				<div class="ui card">
 | 
			
		||||
					<div id="profile-avatar" class="content gt-df">
 | 
			
		||||
					{{if eq .SignedUserID .ContextUser.ID}}
 | 
			
		||||
						<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{.locale.Tr "user.change_avatar"}}">
 | 
			
		||||
							{{/* 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*/}}
 | 
			
		||||
							{{avatar $.Context .ContextUser 256}}
 | 
			
		||||
						</a>
 | 
			
		||||
					{{else}}
 | 
			
		||||
						<span class="image">
 | 
			
		||||
							{{avatar $.Context .ContextUser 256}}
 | 
			
		||||
						</span>
 | 
			
		||||
					{{end}}
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="content gt-word-break profile-avatar-name">
 | 
			
		||||
						{{if .ContextUser.FullName}}<span class="header text center">{{.ContextUser.FullName}}</span>{{end}}
 | 
			
		||||
						<span class="username text center">{{.ContextUser.Name}}</span>
 | 
			
		||||
						{{if .EnableFeed}}
 | 
			
		||||
							<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>
 | 
			
		||||
						{{end}}
 | 
			
		||||
						<div class="gt-mt-3">
 | 
			
		||||
							<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>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="extra content gt-word-break">
 | 
			
		||||
						<ul>
 | 
			
		||||
							{{if .ContextUser.Location}}
 | 
			
		||||
								<li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							{{if (eq .SignedUserID .ContextUser.ID)}}
 | 
			
		||||
								<li>
 | 
			
		||||
									{{svg "octicon-mail"}}
 | 
			
		||||
									<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
 | 
			
		||||
									<a href="{{AppSubUrl}}/user/settings#privacy-user-settings">
 | 
			
		||||
										{{if .ShowUserEmail}}
 | 
			
		||||
											<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
 | 
			
		||||
												{{svg "octicon-unlock"}}
 | 
			
		||||
											</i>
 | 
			
		||||
										{{else}}
 | 
			
		||||
											<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
 | 
			
		||||
												{{svg "octicon-lock"}}
 | 
			
		||||
											</i>
 | 
			
		||||
										{{end}}
 | 
			
		||||
									</a>
 | 
			
		||||
								</li>
 | 
			
		||||
							{{else}}
 | 
			
		||||
								{{if .ShowUserEmail}}
 | 
			
		||||
									<li>
 | 
			
		||||
										{{svg "octicon-mail"}}
 | 
			
		||||
										<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
 | 
			
		||||
									</li>
 | 
			
		||||
								{{end}}
 | 
			
		||||
							{{end}}
 | 
			
		||||
							{{if .ContextUser.Website}}
 | 
			
		||||
								<li>
 | 
			
		||||
									{{svg "octicon-link"}}
 | 
			
		||||
									<a target="_blank" rel="noopener noreferrer me" href="{{.ContextUser.Website}}">{{.ContextUser.Website}}</a>
 | 
			
		||||
								</li>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							{{if $.RenderedDescription}}
 | 
			
		||||
								<li>
 | 
			
		||||
									<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div>
 | 
			
		||||
								</li>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							{{range .OpenIDs}}
 | 
			
		||||
								{{if .Show}}
 | 
			
		||||
									<li>
 | 
			
		||||
										{{svg "fontawesome-openid"}}
 | 
			
		||||
										<a target="_blank" rel="noopener noreferrer" href="{{.URI}}">{{.URI}}</a>
 | 
			
		||||
									</li>
 | 
			
		||||
								{{end}}
 | 
			
		||||
							{{end}}
 | 
			
		||||
							<li>{{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li>
 | 
			
		||||
							{{if and .Orgs .HasOrgsVisible}}
 | 
			
		||||
							<li>
 | 
			
		||||
								<ul class="user-orgs">
 | 
			
		||||
								{{range .Orgs}}
 | 
			
		||||
									{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
 | 
			
		||||
									<li>
 | 
			
		||||
										<a href="{{.HomeLink}}" data-tooltip-content="{{.Name}}">
 | 
			
		||||
											{{avatar $.Context .}}
 | 
			
		||||
										</a>
 | 
			
		||||
									</li>
 | 
			
		||||
									{{end}}
 | 
			
		||||
								{{end}}
 | 
			
		||||
								</ul>
 | 
			
		||||
							</li>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							{{if .Badges}}
 | 
			
		||||
							<li>
 | 
			
		||||
								<ul class="user-badges">
 | 
			
		||||
								{{range .Badges}}
 | 
			
		||||
									<li>
 | 
			
		||||
										<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
 | 
			
		||||
									</li>
 | 
			
		||||
								{{end}}
 | 
			
		||||
								</ul>
 | 
			
		||||
							</li>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
 | 
			
		||||
							<li class="follow">
 | 
			
		||||
								{{if $.IsFollowing}}
 | 
			
		||||
									<form method="post" action="{{.Link}}?action=unfollow&redirect_to={{$.Link}}">
 | 
			
		||||
										{{$.CsrfTokenHtml}}
 | 
			
		||||
										<button type="submit" class="ui basic red button">{{svg "octicon-person"}} {{.locale.Tr "user.unfollow"}}</button>
 | 
			
		||||
									</form>
 | 
			
		||||
								{{else}}
 | 
			
		||||
									<form method="post" action="{{.Link}}?action=follow&redirect_to={{$.Link}}">
 | 
			
		||||
										{{$.CsrfTokenHtml}}
 | 
			
		||||
										<button type="submit" class="ui basic green button">{{svg "octicon-person"}} {{.locale.Tr "user.follow"}}</button>
 | 
			
		||||
									</form>
 | 
			
		||||
								{{end}}
 | 
			
		||||
							</li>
 | 
			
		||||
							{{end}}
 | 
			
		||||
						</ul>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				{{template "shared/user/profile_big_avatar" .}}
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="ui twelve wide column">
 | 
			
		||||
				<div class="gt-mb-4 gt-df">
 | 
			
		||||
				<div class="gt-mb-4">
 | 
			
		||||
					{{template "user/overview/header" .}}
 | 
			
		||||
				</div>
 | 
			
		||||
 | 
			
		||||
@@ -145,12 +30,12 @@
 | 
			
		||||
					{{template "repo/user_cards" .}}
 | 
			
		||||
				{{else if eq .TabName "followers"}}
 | 
			
		||||
					{{template "repo/user_cards" .}}
 | 
			
		||||
				{{else if or (eq .TabName "repositories") (not .ProfileReadme)}}
 | 
			
		||||
				{{else if eq .TabName "overview"}}
 | 
			
		||||
					<div id="readme_profile" class="markup">{{.ProfileReadme | Str2html}}</div>
 | 
			
		||||
				{{else}}
 | 
			
		||||
					{{template "explore/repo_search" .}}
 | 
			
		||||
					{{template "explore/repo_list" .}}
 | 
			
		||||
					{{template "base/paginate" .}}
 | 
			
		||||
				{{else if .ProfileReadme}}
 | 
			
		||||
					<div id="readme_profile" class="render-content markup"> {{$.ProfileReadme|Str2html}} </div>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ Gitea's private styles use `g-` prefix.
 | 
			
		||||
.gt-ab { align-items: baseline !important; }
 | 
			
		||||
.gt-tc { text-align: center !important; }
 | 
			
		||||
.gt-tl { text-align: left !important; }
 | 
			
		||||
.gt-tr { text-align: right !important; } /* TODO: rename these to "gt-text-right", etc. there are only a few */
 | 
			
		||||
.gt-jc { justify-content: center !important; }
 | 
			
		||||
.gt-js { justify-content: flex-start !important; }
 | 
			
		||||
.gt-je { justify-content: flex-end !important; }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user