From a90a215662636fed1a2c67b49cf060e2936822f6 Mon Sep 17 00:00:00 2001
From: Bo-Yi Wu <appleboy.tw@gmail.com>
Date: Sat, 4 Feb 2017 20:20:20 +0800
Subject: [PATCH] feat: Add search bar on user profile page. (#787)

---
 models/repo.go              |  8 +++--
 models/user.go              |  2 +-
 routers/api/v1/repo/repo.go |  2 +-
 routers/user/home.go        |  2 +-
 routers/user/profile.go     | 64 ++++++++++++++++++++++++++++++++++---
 templates/user/profile.tmpl |  1 +
 6 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/models/repo.go b/models/repo.go
index 51e8f6351d..3a503d8953 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -1579,10 +1579,14 @@ func GetRepositoryByID(id int64) (*Repository, error) {
 }
 
 // GetUserRepositories returns a list of repositories of given user.
-func GetUserRepositories(userID int64, private bool, page, pageSize int) ([]*Repository, error) {
+func GetUserRepositories(userID int64, private bool, page, pageSize int, orderBy string) ([]*Repository, error) {
+	if len(orderBy) == 0 {
+		orderBy = "updated_unix DESC"
+	}
+
 	sess := x.
 		Where("owner_id = ?", userID).
-		Desc("updated_unix")
+		OrderBy(orderBy)
 	if !private {
 		sess.And("is_private=?", false)
 	}
diff --git a/models/user.go b/models/user.go
index c4a1ce3d56..c7ceacaa6b 100644
--- a/models/user.go
+++ b/models/user.go
@@ -491,7 +491,7 @@ func (u *User) GetOrganizationCount() (int64, error) {
 
 // GetRepositories returns repositories that user owns, including private repositories.
 func (u *User) GetRepositories(page, pageSize int) (err error) {
-	u.Repos, err = GetUserRepositories(u.ID, true, page, pageSize)
+	u.Repos, err = GetUserRepositories(u.ID, true, page, pageSize, "")
 	return err
 }
 
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index fea625fbe7..d65f30d729 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -80,7 +80,7 @@ func Search(ctx *context.APIContext) {
 // ListMyRepos list all my repositories
 // see https://github.com/gogits/go-gogs-client/wiki/Repositories#list-your-repositories
 func ListMyRepos(ctx *context.APIContext) {
-	ownRepos, err := models.GetUserRepositories(ctx.User.ID, true, 1, ctx.User.NumRepos)
+	ownRepos, err := models.GetUserRepositories(ctx.User.ID, true, 1, ctx.User.NumRepos, "")
 	if err != nil {
 		ctx.Error(500, "GetRepositories", err)
 		return
diff --git a/routers/user/home.go b/routers/user/home.go
index e043f67bea..09711f4bc0 100644
--- a/routers/user/home.go
+++ b/routers/user/home.go
@@ -383,7 +383,7 @@ func showOrgProfile(ctx *context.Context) {
 		ctx.Data["Repos"] = repos
 	} else {
 		showPrivate := ctx.IsSigned && ctx.User.IsAdmin
-		repos, err = models.GetUserRepositories(org.ID, showPrivate, page, setting.UI.User.RepoPagingNum)
+		repos, err = models.GetUserRepositories(org.ID, showPrivate, page, setting.UI.User.RepoPagingNum, "")
 		if err != nil {
 			ctx.Handle(500, "GetRepositories", err)
 			return
diff --git a/routers/user/profile.go b/routers/user/profile.go
index 857b9e3f5b..3b4d5a6b3c 100644
--- a/routers/user/profile.go
+++ b/routers/user/profile.go
@@ -109,12 +109,66 @@ func Profile(ctx *context.Context) {
 			page = 1
 		}
 
-		ctx.Data["Repos"], err = models.GetUserRepositories(ctxUser.ID, showPrivate, page, setting.UI.User.RepoPagingNum)
-		if err != nil {
-			ctx.Handle(500, "GetRepositories", err)
-			return
+		var (
+			repos   []*models.Repository
+			count   int64
+			err     error
+			orderBy string
+		)
+		switch ctx.Query("sort") {
+		case "newest":
+			orderBy = "created_unix DESC"
+		case "oldest":
+			orderBy = "created_unix ASC"
+		case "recentupdate":
+			orderBy = "updated_unix DESC"
+		case "leastupdate":
+			orderBy = "updated_unix ASC"
+		case "reversealphabetically":
+			orderBy = "name DESC"
+		case "alphabetically":
+			orderBy = "name ASC"
+		default:
+			orderBy = "updated_unix DESC"
 		}
-		ctx.Data["Page"] = paginater.New(ctxUser.NumRepos, setting.UI.User.RepoPagingNum, page, 5)
+
+		keyword := ctx.Query("q")
+		if len(keyword) == 0 {
+			repos, err = models.GetUserRepositories(ctxUser.ID, showPrivate, page, setting.UI.User.RepoPagingNum, orderBy)
+			if err != nil {
+				ctx.Handle(500, "GetRepositories", err)
+				return
+			}
+			ctx.Data["Repos"] = repos
+			ctx.Data["Page"] = paginater.New(ctxUser.NumRepos, setting.UI.User.RepoPagingNum, page, 5)
+			ctx.Data["Total"] = ctxUser.NumRepos
+		} else {
+			repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
+				Keyword:  keyword,
+				OwnerID:  ctxUser.ID,
+				OrderBy:  orderBy,
+				Private:  ctx.IsSigned && ctx.User.ID == ctxUser.ID,
+				Page:     page,
+				PageSize: setting.UI.User.RepoPagingNum,
+			})
+			if err != nil {
+				ctx.Handle(500, "SearchRepositoryByName", err)
+				return
+			}
+
+			ctx.Data["Repos"] = repos
+			ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
+			ctx.Data["Total"] = count
+		}
+
+		// set default sort value.
+		if ctx.Query("sort") == "" {
+			ctx.Data["SortType"] = "recentupdate"
+		} else {
+			ctx.Data["SortType"] = ctx.Query("sort")
+		}
+
+		ctx.Data["Keyword"] = keyword
 	}
 
 	ctx.HTML(200, tplProfile)
diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl
index 198a9e3b60..d93ceb8274 100644
--- a/templates/user/profile.tmpl
+++ b/templates/user/profile.tmpl
@@ -95,6 +95,7 @@
 						{{template "explore/repo_list" .}}
 					</div>
 				{{else}}
+					{{template "explore/search" .}}
 					{{template "explore/repo_list" .}}
 					{{template "base/paginate" .}}
 				{{end}}