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("", user.Profile) | ||||||
| 			m.Get("/followers", user.Followers) | 			m.Get("/followers", user.Followers) | ||||||
| 			m.Get("/following", user.Following) | 			m.Get("/following", user.Following) | ||||||
| 			m.Get("/stars", user.Stars) |  | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 		m.Get("/attachments/:uuid", func(ctx *context.Context) { | 		m.Get("/attachments/:uuid", func(ctx *context.Context) { | ||||||
|  | |||||||
| @ -2146,66 +2146,6 @@ func NotifyWatchers(act *Action) error { | |||||||
| 	return notifyWatchers(x, act) | 	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 | account_settings = Account Settings | ||||||
| settings = Settings | settings = Settings | ||||||
| your_profile = Your Profile | your_profile = Your Profile | ||||||
|  | your_starred = Your starred | ||||||
| your_settings = Your Settings | your_settings = Your Settings | ||||||
| 
 | 
 | ||||||
| activities = Activities | activities = Activities | ||||||
|  | |||||||
| @ -95,6 +95,14 @@ func Profile(ctx *context.Context) { | |||||||
| 		if ctx.Written() { | 		if ctx.Written() { | ||||||
| 			return | 			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: | 	default: | ||||||
| 		page := ctx.QueryInt("page") | 		page := ctx.QueryInt("page") | ||||||
| 		if page <= 0 { | 		if page <= 0 { | ||||||
| @ -138,11 +146,6 @@ func Following(ctx *context.Context) { | |||||||
| 	repo.RenderUserCards(ctx, u.NumFollowing, u.GetFollowing, tplFollowers) | 	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
 | // Action response for follow/unfollow user request
 | ||||||
| func Action(ctx *context.Context) { | func Action(ctx *context.Context) { | ||||||
| 	u := GetUserByParams(ctx) | 	u := GetUserByParams(ctx) | ||||||
|  | |||||||
| @ -116,6 +116,10 @@ | |||||||
| 													<i class="octicon octicon-person"></i> | 													<i class="octicon octicon-person"></i> | ||||||
| 													{{.i18n.Tr "your_profile"}}<!-- Your profile --> | 													{{.i18n.Tr "your_profile"}}<!-- Your profile --> | ||||||
| 												</a> | 												</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"> | 												<a class="{{if .PageIsUserSettings}}active{{end}} item" href="{{AppSubUrl}}/user/settings"> | ||||||
| 													<i class="octicon octicon-settings"></i> | 													<i class="octicon octicon-settings"></i> | ||||||
| 													{{.i18n.Tr "your_settings"}}<!-- Your settings --> | 													{{.i18n.Tr "your_settings"}}<!-- Your settings --> | ||||||
|  | |||||||
| @ -75,23 +75,28 @@ | |||||||
| 			</div> | 			</div> | ||||||
| 			<div class="ui eleven wide column"> | 			<div class="ui eleven wide column"> | ||||||
| 				<div class="ui secondary pointing menu"> | 				<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"}} | 						<i class="octicon octicon-repo"></i> {{.i18n.Tr "user.repositories"}} | ||||||
| 					</a> | 					</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"}} | ||||||
| 							<i class="octicon octicon-rss"></i> {{.i18n.Tr "user.activity"}} | 					</a> | ||||||
| 						</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> | 					</a> | ||||||
| 				</div> | 				</div> | ||||||
| 				{{if ne .TabName "activity"}} | 
 | ||||||
| 					{{template "explore/repo_list" .}} | 				{{if eq .TabName "activity"}} | ||||||
| 					{{template "base/paginate" .}} |  | ||||||
| 				{{else}} |  | ||||||
| 					<br> |  | ||||||
| 					<div class="feeds"> | 					<div class="feeds"> | ||||||
| 						{{template "user/dashboard/feeds" .}} | 						{{template "user/dashboard/feeds" .}} | ||||||
| 					</div> | 					</div> | ||||||
|  | 				{{else if eq .TabName "stars"}} | ||||||
|  | 					<div class="stars"> | ||||||
|  | 						{{template "explore/repo_list" .}} | ||||||
|  | 					</div> | ||||||
|  | 				{{else}} | ||||||
|  | 					{{template "explore/repo_list" .}} | ||||||
|  | 					{{template "base/paginate" .}} | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user