Skip to content

Commit

Permalink
Tab on user profile to show starred repos (#519)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
andreynering authored and lunny committed Dec 29, 2016
1 parent 2d1a1fc commit b992858
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 76 deletions.
1 change: 0 additions & 1 deletion cmd/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
60 changes: 0 additions & 60 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

// ___________ __
// \_ _____/__________| | __
// | __)/ _ \_ __ \ |/ /
Expand Down
87 changes: 87 additions & 0 deletions models/star.go
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 8 additions & 5 deletions routers/user/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions templates/base/head.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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 -->
Expand Down
25 changes: 15 additions & 10 deletions templates/user/profile.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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">
<i class="octicon octicon-rss"></i> {{.i18n.Tr "user.activity"}}
</a>
<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>
Expand Down

0 comments on commit b992858

Please sign in to comment.