Tab on user profile to show starred repos (#519)
* Tab on user profile to show starred repos * Make golint happy and use transactions on StarRepo function * x -> sess * Use sess.Close() instead of sess.Rollback() * Add copyright * Fix lint
This commit is contained in:
		
							parent
							
								
									2d1a1fce93
								
							
						
					
					
						commit
						b992858883
					
				| @ -273,7 +273,6 @@ func runWeb(ctx *cli.Context) error { | ||||
| 			m.Get("", user.Profile) | ||||
| 			m.Get("/followers", user.Followers) | ||||
| 			m.Get("/following", user.Following) | ||||
| 			m.Get("/stars", user.Stars) | ||||
| 		}) | ||||
| 
 | ||||
| 		m.Get("/attachments/:uuid", func(ctx *context.Context) { | ||||
|  | ||||
| @ -2146,66 +2146,6 @@ func NotifyWatchers(act *Action) error { | ||||
| 	return notifyWatchers(x, act) | ||||
| } | ||||
| 
 | ||||
| //   _________ __
 | ||||
| //  /   _____//  |______ _______
 | ||||
| //  \_____  \\   __\__  \\_  __ \
 | ||||
| //  /        \|  |  / __ \|  | \/
 | ||||
| // /_______  /|__| (____  /__|
 | ||||
| //         \/           \/
 | ||||
| 
 | ||||
| // Star contains the star information
 | ||||
| type Star struct { | ||||
| 	ID     int64 `xorm:"pk autoincr"` | ||||
| 	UID    int64 `xorm:"UNIQUE(s)"` | ||||
| 	RepoID int64 `xorm:"UNIQUE(s)"` | ||||
| } | ||||
| 
 | ||||
| // StarRepo star or unstar repository.
 | ||||
| func StarRepo(userID, repoID int64, star bool) (err error) { | ||||
| 	if star { | ||||
| 		if IsStaring(userID, repoID) { | ||||
| 			return nil | ||||
| 		} | ||||
| 		if _, err = x.Insert(&Star{UID: userID, RepoID: repoID}); err != nil { | ||||
| 			return err | ||||
| 		} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoID); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		_, err = x.Exec("UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", userID) | ||||
| 	} else { | ||||
| 		if !IsStaring(userID, repoID) { | ||||
| 			return nil | ||||
| 		} | ||||
| 		if _, err = x.Delete(&Star{0, userID, repoID}); err != nil { | ||||
| 			return err | ||||
| 		} else if _, err = x.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoID); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		_, err = x.Exec("UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", userID) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // IsStaring checks if user has starred given repository.
 | ||||
| func IsStaring(userID, repoID int64) bool { | ||||
| 	has, _ := x.Get(&Star{0, userID, repoID}) | ||||
| 	return has | ||||
| } | ||||
| 
 | ||||
| // GetStargazers returns the users who gave stars to this repository
 | ||||
| func (repo *Repository) GetStargazers(page int) ([]*User, error) { | ||||
| 	users := make([]*User, 0, ItemsPerPage) | ||||
| 	sess := x. | ||||
| 		Limit(ItemsPerPage, (page-1)*ItemsPerPage). | ||||
| 		Where("star.repo_id=?", repo.ID) | ||||
| 	if setting.UsePostgreSQL { | ||||
| 		sess = sess.Join("LEFT", "star", `"user".id=star.uid`) | ||||
| 	} else { | ||||
| 		sess = sess.Join("LEFT", "star", "user.id=star.uid") | ||||
| 	} | ||||
| 	return users, sess.Find(&users) | ||||
| } | ||||
| 
 | ||||
| // ___________           __
 | ||||
| // \_   _____/__________|  | __
 | ||||
| //  |    __)/  _ \_  __ \  |/ /
 | ||||
|  | ||||
							
								
								
									
										87
									
								
								models/star.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								models/star.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| // Copyright 2016 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package models | ||||
| 
 | ||||
| // Star represents a starred repo by an user.
 | ||||
| type Star struct { | ||||
| 	ID     int64 `xorm:"pk autoincr"` | ||||
| 	UID    int64 `xorm:"UNIQUE(s)"` | ||||
| 	RepoID int64 `xorm:"UNIQUE(s)"` | ||||
| } | ||||
| 
 | ||||
| // StarRepo or unstar repository.
 | ||||
| func StarRepo(userID, repoID int64, star bool) error { | ||||
| 	sess := x.NewSession() | ||||
| 
 | ||||
| 	defer sess.Close() | ||||
| 
 | ||||
| 	if err := sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if star { | ||||
| 		if IsStaring(userID, repoID) { | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		if _, err := sess.Insert(&Star{UID: userID, RepoID: repoID}); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if _, err := sess.Exec("UPDATE `repository` SET num_stars = num_stars + 1 WHERE id = ?", repoID); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if _, err := sess.Exec("UPDATE `user` SET num_stars = num_stars + 1 WHERE id = ?", userID); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		if !IsStaring(userID, repoID) { | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		if _, err := sess.Delete(&Star{0, userID, repoID}); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if _, err := sess.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoID); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if _, err := sess.Exec("UPDATE `user` SET num_stars = num_stars - 1 WHERE id = ?", userID); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
| // IsStaring checks if user has starred given repository.
 | ||||
| func IsStaring(userID, repoID int64) bool { | ||||
| 	has, _ := x.Get(&Star{0, userID, repoID}) | ||||
| 	return has | ||||
| } | ||||
| 
 | ||||
| // GetStargazers returns the users that starred the repo.
 | ||||
| func (repo *Repository) GetStargazers(page int) ([]*User, error) { | ||||
| 	users := make([]*User, 0, ItemsPerPage) | ||||
| 	err := x. | ||||
| 		Limit(ItemsPerPage, (page-1)*ItemsPerPage). | ||||
| 		Where("star.repo_id = ?", repo.ID). | ||||
| 		Join("LEFT", "star", "`user`.id = star.uid"). | ||||
| 		Find(&users) | ||||
| 	return users, err | ||||
| } | ||||
| 
 | ||||
| // GetStarredRepos returns the repos the user starred.
 | ||||
| func (u *User) GetStarredRepos(private bool) (repos []*Repository, err error) { | ||||
| 	sess := x. | ||||
| 		Join("INNER", "star", "star.repo_id = repository.id"). | ||||
| 		Where("star.uid = ?", u.ID) | ||||
| 
 | ||||
| 	if !private { | ||||
| 		sess = sess.And("is_private = ?", false) | ||||
| 	} | ||||
| 
 | ||||
| 	err = sess. | ||||
| 		Find(&repos) | ||||
| 	return | ||||
| } | ||||
| @ -36,6 +36,7 @@ admin_panel = Admin Panel | ||||
| account_settings = Account Settings | ||||
| settings = Settings | ||||
| your_profile = Your Profile | ||||
| your_starred = Your starred | ||||
| your_settings = Your Settings | ||||
| 
 | ||||
| activities = Activities | ||||
|  | ||||
| @ -95,6 +95,14 @@ func Profile(ctx *context.Context) { | ||||
| 		if ctx.Written() { | ||||
| 			return | ||||
| 		} | ||||
| 	case "stars": | ||||
| 		showPrivateRepos := ctx.IsSigned && ctx.User.ID == ctxUser.ID | ||||
| 		starredRepos, err := ctxUser.GetStarredRepos(showPrivateRepos) | ||||
| 		if err != nil { | ||||
| 			ctx.Handle(500, "GetStarredRepos", err) | ||||
| 			return | ||||
| 		} | ||||
| 		ctx.Data["Repos"] = starredRepos | ||||
| 	default: | ||||
| 		page := ctx.QueryInt("page") | ||||
| 		if page <= 0 { | ||||
| @ -138,11 +146,6 @@ func Following(ctx *context.Context) { | ||||
| 	repo.RenderUserCards(ctx, u.NumFollowing, u.GetFollowing, tplFollowers) | ||||
| } | ||||
| 
 | ||||
| // Stars show repositories user starred
 | ||||
| func Stars(ctx *context.Context) { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // Action response for follow/unfollow user request
 | ||||
| func Action(ctx *context.Context) { | ||||
| 	u := GetUserByParams(ctx) | ||||
|  | ||||
| @ -116,6 +116,10 @@ | ||||
| 													<i class="octicon octicon-person"></i> | ||||
| 													{{.i18n.Tr "your_profile"}}<!-- Your profile --> | ||||
| 												</a> | ||||
| 												<a class="item" href="{{AppSubUrl}}/{{.SignedUser.Name}}?tab=stars"> | ||||
| 													<i class="octicon octicon-star"></i> | ||||
| 													{{.i18n.Tr "your_starred"}} | ||||
| 												</a> | ||||
| 												<a class="{{if .PageIsUserSettings}}active{{end}} item" href="{{AppSubUrl}}/user/settings"> | ||||
| 													<i class="octicon octicon-settings"></i> | ||||
| 													{{.i18n.Tr "your_settings"}}<!-- Your settings --> | ||||
|  | ||||
| @ -75,23 +75,28 @@ | ||||
| 			</div> | ||||
| 			<div class="ui eleven wide column"> | ||||
| 				<div class="ui secondary pointing menu"> | ||||
| 					<a class="{{if ne .TabName "activity"}}active{{end}} item" href="{{.Owner.HomeLink}}"> | ||||
| 					<a class='{{if and (ne .TabName "activity") (ne .TabName "stars")}}active{{end}} item' href="{{.Owner.HomeLink}}"> | ||||
| 						<i class="octicon octicon-repo"></i> {{.i18n.Tr "user.repositories"}} | ||||
| 					</a> | ||||
| 					<a class="item"> | ||||
| 						<a class="{{if eq .TabName "activity"}}active{{end}} item" href="{{.Owner.HomeLink}}?tab=activity"> | ||||
| 					<a class='{{if eq .TabName "activity"}}active{{end}} item' href="{{.Owner.HomeLink}}?tab=activity"> | ||||
| 						<i class="octicon octicon-rss"></i> {{.i18n.Tr "user.activity"}} | ||||
| 					</a> | ||||
| 					<a class='{{if eq .TabName "stars"}}active{{end}} item' href="{{.Owner.HomeLink}}?tab=stars"> | ||||
| 						<i class="octicon octicon-star"></i> {{.i18n.Tr "user.starred"}} | ||||
| 					</a> | ||||
| 				</div> | ||||
| 				{{if ne .TabName "activity"}} | ||||
| 					{{template "explore/repo_list" .}} | ||||
| 					{{template "base/paginate" .}} | ||||
| 				{{else}} | ||||
| 					<br> | ||||
| 
 | ||||
| 				{{if eq .TabName "activity"}} | ||||
| 					<div class="feeds"> | ||||
| 						{{template "user/dashboard/feeds" .}} | ||||
| 					</div> | ||||
| 				{{else if eq .TabName "stars"}} | ||||
| 					<div class="stars"> | ||||
| 						{{template "explore/repo_list" .}} | ||||
| 					</div> | ||||
| 				{{else}} | ||||
| 					{{template "explore/repo_list" .}} | ||||
| 					{{template "base/paginate" .}} | ||||
| 				{{end}} | ||||
| 			</div> | ||||
| 		</div> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user