mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Sort users and orgs on explore by recency by default (#24279)
This gives more "freshness" to the explore page. So it's not just the same X users on the explore page by default, now it matches the same sort as the repos on the explore page. --------- Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
		@@ -65,3 +65,8 @@ func (ctx *Context) FormOptionalBool(key string) util.OptionalBool {
 | 
				
			|||||||
	v = v || strings.EqualFold(s, "on")
 | 
						v = v || strings.EqualFold(s, "on")
 | 
				
			||||||
	return util.OptionalBoolOf(v)
 | 
						return util.OptionalBoolOf(v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *Context) SetFormString(key, value string) {
 | 
				
			||||||
 | 
						_ = ctx.Req.FormValue(key) // force parse form
 | 
				
			||||||
 | 
						ctx.Req.Form.Set(key, value)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,10 @@ func Organizations(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Title"] = ctx.Tr("admin.organizations")
 | 
						ctx.Data["Title"] = ctx.Tr("admin.organizations")
 | 
				
			||||||
	ctx.Data["PageIsAdminOrganizations"] = true
 | 
						ctx.Data["PageIsAdminOrganizations"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.FormString("sort") == "" {
 | 
				
			||||||
 | 
							ctx.SetFormString("sort", explore.UserSearchDefaultAdminSort)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{
 | 
						explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{
 | 
				
			||||||
		Actor: ctx.Doer,
 | 
							Actor: ctx.Doer,
 | 
				
			||||||
		Type:  user_model.UserTypeOrganization,
 | 
							Type:  user_model.UserTypeOrganization,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,7 +53,8 @@ func Users(ctx *context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	sortType := ctx.FormString("sort")
 | 
						sortType := ctx.FormString("sort")
 | 
				
			||||||
	if sortType == "" {
 | 
						if sortType == "" {
 | 
				
			||||||
		sortType = explore.UserSearchDefaultSortType
 | 
							sortType = explore.UserSearchDefaultAdminSort
 | 
				
			||||||
 | 
							ctx.SetFormString("sort", sortType)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.PageData["adminUserListSearchForm"] = map[string]interface{}{
 | 
						ctx.PageData["adminUserListSearchForm"] = map[string]interface{}{
 | 
				
			||||||
		"StatusFilterMap": statusFilterMap,
 | 
							"StatusFilterMap": statusFilterMap,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,10 @@ func Organizations(ctx *context.Context) {
 | 
				
			|||||||
		visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate)
 | 
							visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.FormString("sort") == "" {
 | 
				
			||||||
 | 
							ctx.SetFormString("sort", UserSearchDefaultSortType)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RenderUserSearch(ctx, &user_model.SearchUserOptions{
 | 
						RenderUserSearch(ctx, &user_model.SearchUserOptions{
 | 
				
			||||||
		Actor:       ctx.Doer,
 | 
							Actor:       ctx.Doer,
 | 
				
			||||||
		Type:        user_model.UserTypeOrganization,
 | 
							Type:        user_model.UserTypeOrganization,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,10 @@ const (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UserSearchDefaultSortType is the default sort type for user search
 | 
					// UserSearchDefaultSortType is the default sort type for user search
 | 
				
			||||||
const UserSearchDefaultSortType = "alphabetically"
 | 
					const (
 | 
				
			||||||
 | 
						UserSearchDefaultSortType  = "recentupdate"
 | 
				
			||||||
 | 
						UserSearchDefaultAdminSort = "alphabetically"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var nullByte = []byte{0x00}
 | 
					var nullByte = []byte{0x00}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,14 +59,13 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// we can not set orderBy to `models.SearchOrderByXxx`, because there may be a JOIN in the statement, different tables may have the same name columns
 | 
						// we can not set orderBy to `models.SearchOrderByXxx`, because there may be a JOIN in the statement, different tables may have the same name columns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["SortType"] = ctx.FormString("sort")
 | 
						ctx.Data["SortType"] = ctx.FormString("sort")
 | 
				
			||||||
	switch ctx.FormString("sort") {
 | 
						switch ctx.FormString("sort") {
 | 
				
			||||||
	case "newest":
 | 
						case "newest":
 | 
				
			||||||
		orderBy = "`user`.id DESC"
 | 
							orderBy = "`user`.id DESC"
 | 
				
			||||||
	case "oldest":
 | 
						case "oldest":
 | 
				
			||||||
		orderBy = "`user`.id ASC"
 | 
							orderBy = "`user`.id ASC"
 | 
				
			||||||
	case "recentupdate":
 | 
					 | 
				
			||||||
		orderBy = "`user`.updated_unix DESC"
 | 
					 | 
				
			||||||
	case "leastupdate":
 | 
						case "leastupdate":
 | 
				
			||||||
		orderBy = "`user`.updated_unix ASC"
 | 
							orderBy = "`user`.updated_unix ASC"
 | 
				
			||||||
	case "reversealphabetically":
 | 
						case "reversealphabetically":
 | 
				
			||||||
@@ -72,10 +74,14 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
 | 
				
			|||||||
		orderBy = "`user`.last_login_unix ASC"
 | 
							orderBy = "`user`.last_login_unix ASC"
 | 
				
			||||||
	case "reverselastlogin":
 | 
						case "reverselastlogin":
 | 
				
			||||||
		orderBy = "`user`.last_login_unix DESC"
 | 
							orderBy = "`user`.last_login_unix DESC"
 | 
				
			||||||
	case UserSearchDefaultSortType: // "alphabetically"
 | 
						case "alphabetically":
 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		orderBy = "`user`.name ASC"
 | 
							orderBy = "`user`.name ASC"
 | 
				
			||||||
		ctx.Data["SortType"] = UserSearchDefaultSortType
 | 
						case "recentupdate":
 | 
				
			||||||
 | 
							fallthrough
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// in case the sortType is not valid, we set it to recentupdate
 | 
				
			||||||
 | 
							ctx.Data["SortType"] = "recentupdate"
 | 
				
			||||||
 | 
							orderBy = "`user`.updated_unix DESC"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts.Keyword = ctx.FormTrim("q")
 | 
						opts.Keyword = ctx.FormTrim("q")
 | 
				
			||||||
@@ -127,6 +133,10 @@ func Users(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["PageIsExploreUsers"] = true
 | 
						ctx.Data["PageIsExploreUsers"] = true
 | 
				
			||||||
	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 | 
						ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.FormString("sort") == "" {
 | 
				
			||||||
 | 
							ctx.SetFormString("sort", UserSearchDefaultSortType)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RenderUserSearch(ctx, &user_model.SearchUserOptions{
 | 
						RenderUserSearch(ctx, &user_model.SearchUserOptions{
 | 
				
			||||||
		Actor:       ctx.Doer,
 | 
							Actor:       ctx.Doer,
 | 
				
			||||||
		Type:        user_model.UserTypeIndividual,
 | 
							Type:        user_model.UserTypeIndividual,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) {
 | 
				
			|||||||
	setting.UI.ShowUserEmail = true
 | 
						setting.UI.ShowUserEmail = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	session := loginUser(t, "user2")
 | 
						session := loginUser(t, "user2")
 | 
				
			||||||
	req := NewRequest(t, "GET", "/explore/users")
 | 
						req := NewRequest(t, "GET", "/explore/users?sort=alphabetically")
 | 
				
			||||||
	resp := session.MakeRequest(t, req, http.StatusOK)
 | 
						resp := session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
	htmlDoc := NewHTMLParser(t, resp.Body)
 | 
						htmlDoc := NewHTMLParser(t, resp.Body)
 | 
				
			||||||
	assert.Contains(t,
 | 
						assert.Contains(t,
 | 
				
			||||||
@@ -30,7 +30,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	setting.UI.ShowUserEmail = false
 | 
						setting.UI.ShowUserEmail = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req = NewRequest(t, "GET", "/explore/users")
 | 
						req = NewRequest(t, "GET", "/explore/users?sort=alphabetically")
 | 
				
			||||||
	resp = session.MakeRequest(t, req, http.StatusOK)
 | 
						resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
	htmlDoc = NewHTMLParser(t, resp.Body)
 | 
						htmlDoc = NewHTMLParser(t, resp.Body)
 | 
				
			||||||
	assert.NotContains(t,
 | 
						assert.NotContains(t,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user