Skip to content

Feat: Star List #33278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
85f3da9
Feat: Star List
hiifong Jan 15, 2025
0cd54c0
Merge branch 'main' into star/list
hiifong Jan 15, 2025
83cd897
Update
hiifong Jan 20, 2025
9441e3f
Merge branch 'main' into star/list
hiifong Feb 4, 2025
a530419
fix model
hiifong Feb 4, 2025
f1d9ba1
save
hiifong Feb 4, 2025
eeefd0f
Update
hiifong Feb 5, 2025
81cff53
Update
hiifong Feb 5, 2025
a68baa0
Merge branch 'main' into star/list
hiifong Feb 5, 2025
f99f919
Update
hiifong Feb 21, 2025
ef9206f
Update
hiifong Feb 22, 2025
05c56b2
Update
hiifong Feb 22, 2025
975867f
Update
hiifong Feb 22, 2025
001808a
Merge main
hiifong Feb 22, 2025
bfca439
Merge branch 'main' into star/list
hiifong Feb 22, 2025
ef245af
Update
hiifong Feb 24, 2025
c78adb4
Update
hiifong Feb 24, 2025
5cfead5
Merge remote-tracking branch 'origin/star/list' into star/list
hiifong Feb 24, 2025
d7164df
Merge branch 'main' into star/list
hiifong Feb 24, 2025
7306b54
Update
hiifong Feb 24, 2025
aa38a6e
Merge branch 'go-gitea:main' into star/list
hiifong Feb 25, 2025
da0b2e6
Update
hiifong Feb 25, 2025
0d6eba4
Update
hiifong Feb 25, 2025
67306f8
Update
hiifong Feb 25, 2025
af513b0
Merge branch 'main' into star/list
hiifong Feb 26, 2025
ac96f3f
Update
hiifong Feb 26, 2025
02a2ea5
Update
hiifong Feb 26, 2025
4f10b44
Merge branch 'main' into star/list
hiifong Feb 27, 2025
884a470
Update
hiifong Feb 27, 2025
85227d0
Merge branch 'main' into star/list
hiifong Feb 27, 2025
0d9ac76
Merge branch 'go-gitea:main' into star/list
hiifong Feb 28, 2025
ba8fad9
rename
hiifong Apr 7, 2025
cc4eefa
Merge upstream/main into star/list
hiifong Apr 7, 2025
5b0ca5f
Update
hiifong Apr 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ func prepareMigrationTasks() []*migration {
newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
newMigration(317, "Add new index for action for heatmap", v1_24.AddNewIndexForUserDashboard),
newMigration(318, "Add anonymous_access_mode for repo_unit", v1_24.AddRepoUnitAnonymousAccessMode),
newMigration(319, "Add star_list, star_list_repo table", v1_24.AddStarList),
}
return preparedMigrations
}
Expand Down
44 changes: 44 additions & 0 deletions models/migrations/v1_24/v319.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_24 //nolint

import (
"code.gitea.io/gitea/modules/timeutil"

"xorm.io/xorm"
)

type StarList struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX"`
Name string
Desc string

CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}

type StarListRepo struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE(s)"`
StarListID int64 `xorm:"UNIQUE(s)"`
RepoID int64 `xorm:"UNIQUE(s)"`
}

func AddStarList(x *xorm.Engine) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
err := sess.Sync(new(StarList))
if err != nil {
return err
}
err = sess.Sync(new(StarListRepo))
if err != nil {
return err
}
return sess.Commit()
}
7 changes: 0 additions & 7 deletions models/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ import (
"code.gitea.io/gitea/modules/setting"
)

// ___________.__ ___________ __
// \__ ___/|__| _____ ___\__ ___/___________ ____ | | __ ___________
// | | | |/ \_/ __ \| | \_ __ \__ \ _/ ___\| |/ // __ \_ __ \
// | | | | Y Y \ ___/| | | | \// __ \\ \___| <\ ___/| | \/
// |____| |__|__|_| /\___ >____| |__| (____ /\___ >__|_ \\___ >__|
// \/ \/ \/ \/ \/ \/

// CanEnableTimetracker returns true when the server admin enabled time tracking
// This overrules IsTimetrackerEnabled
func (repo *Repository) CanEnableTimetracker() bool {
Expand Down
7 changes: 0 additions & 7 deletions models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -755,13 +755,6 @@ func (repo *Repository) MustNotBeArchived() error {
return nil
}

// __________ .__ __
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ |
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
// \/ \/|__| \/ \/

// ErrRepoNotExist represents a "RepoNotExist" kind of error.
type ErrRepoNotExist struct {
ID int64
Expand Down
58 changes: 58 additions & 0 deletions models/repo/star_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package repo

import (
"context"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/timeutil"
)

type StarList struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX"`
Name string
Desc string

Repos []Repository `xorm:"-"`

CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}

func init() {
db.RegisterModel(new(StarList))
}

func InsertStarList(ctx context.Context, starList *StarList) error {
_, err := db.GetEngine(ctx).Insert(starList)
return err
}

func UpdateStarList(ctx context.Context, starList *StarList) error {
_, err := db.GetEngine(ctx).Where("id = ?", starList.ID).AllCols().Update(starList)
return err
}

func DeleteStarListByID(ctx context.Context, id int64) error {
_, err := db.GetEngine(ctx).Delete(&StarList{ID: id})
return err
}

func GetStarListByID(ctx context.Context, id int64) (*StarList, error) {
starList := new(StarList)
if has, err := db.GetEngine(ctx).Where("id = ?", id).Get(starList); err != nil {
return nil, err
} else if !has {
return nil, nil
}
return starList, nil
}

func GetStarListsForUser(ctx context.Context, id int64) ([]*StarList, error) {
starLists := make([]*StarList, 0, 10)
err := db.GetEngine(ctx).Where("uid = ?", id).Find(&starLists)
return starLists, err
}
55 changes: 55 additions & 0 deletions models/repo/star_list_repo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package repo

import (
"context"

"code.gitea.io/gitea/models/db"
)

type StarListRepo struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE(s)"`
StarListID int64 `xorm:"UNIQUE(s)"`
RepoID int64 `xorm:"UNIQUE(s)"`
}

func init() {
db.RegisterModel(new(StarListRepo))
}

func StarLists(ctx context.Context, uid, repoID int64, ids []int64) error {
starListRepos := make([]*StarListRepo, 0, len(ids))
for _, id := range ids {
starListRepos = append(starListRepos, &StarListRepo{
UID: uid,
StarListID: id,
RepoID: repoID,
})
}

ctx, committer, err := db.TxContext(ctx)
if err != nil {
return err
}
defer committer.Close()

_, err = db.GetEngine(ctx).Insert(&starListRepos)
if err != nil {
return err
}

_, err = db.GetEngine(ctx).Where("uid = ? AND repo_id = ? AND star_list_id NOT IN (?)", uid, repoID, ids).Delete(new(StarListRepo))
if err != nil {
return err
}

return committer.Commit()
}

func UnStarLists(ctx context.Context, uid, repoID int64, ids []int64) error {
_, err := db.GetEngine(ctx).Where("uid = ? AND repo_id = ? AND star_list_id NOT IN (?)", uid, repoID, ids).Delete(new(StarListRepo))
if err != nil {
return err
}
return nil
}
8 changes: 8 additions & 0 deletions routers/web/repo/view_home.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,14 @@ func Home(ctx *context.Context) {
ctx.Data["ParentPath"] = "/" + paths[len(paths)-2]
}
}

starList, err := repo_model.GetStarListsForUser(ctx, ctx.Doer.ID)
if err != nil {
ctx.ServerError("SearchStarList", err)
return
}
log.Error("=============================")
ctx.Data["StarList"] = starList
ctx.Data["Paths"] = paths
ctx.Data["TreeLink"] = treeLink
ctx.Data["TreeNames"] = treeNames
Expand Down
47 changes: 47 additions & 0 deletions routers/web/shared/starlists/star_lists.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package starlists

import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
)

func GetByName(ctx *context.Context) {

Check failure on line 12 in routers/web/shared/starlists/star_lists.go

View workflow job for this annotation

GitHub Actions / lint-backend

File is not properly formatted (gofumpt)

Check failure on line 12 in routers/web/shared/starlists/star_lists.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

File is not properly formatted (gofumpt)

Check failure on line 12 in routers/web/shared/starlists/star_lists.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

File is not properly formatted (gofumpt)
}

func Create(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.StarListForm)

log.Info("form: %+v", *form)

err := repo_model.InsertStarList(ctx, &repo_model.StarList{
UID: ctx.Doer.ID,
Name: form.Name,
Desc: form.Desc,
})
if err != nil {
ctx.ServerError("InsertStarList", err)
return
}

ctx.Redirect(ctx.Doer.HomeLink() + "?tab=stars")
}

func UpdateByName(ctx *context.Context) {

}

func DeleteByName(ctx *context.Context) {

}

func List(ctx *context.Context) {

}

func UpdateListRepos(ctx *context.Context) {

}
6 changes: 6 additions & 0 deletions routers/web/user/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
total = int(count)
case "stars":
ctx.Data["PageIsProfileStarList"] = true
starList, err := repo_model.GetStarListsForUser(ctx, ctx.ContextUser.ID)
if err != nil {
ctx.ServerError("SearchStarList", err)
return
}
ctx.Data["StarList"] = starList
repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
PageSize: pagingNum,
Expand Down
13 changes: 13 additions & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
repo_setting "code.gitea.io/gitea/routers/web/repo/setting"
shared_actions "code.gitea.io/gitea/routers/web/shared/actions"
"code.gitea.io/gitea/routers/web/shared/project"
"code.gitea.io/gitea/routers/web/shared/starlists"
"code.gitea.io/gitea/routers/web/user"
user_setting "code.gitea.io/gitea/routers/web/user/setting"
"code.gitea.io/gitea/routers/web/user/setting/security"
Expand Down Expand Up @@ -1620,6 +1621,18 @@ func registerWebRoutes(m *web.Router) {
m.Post("/action/{action:accept_transfer|reject_transfer}", reqSignIn, repo.ActionTransfer)
}, optSignIn, context.RepoAssignment)

m.Group("/stars/lists", func() {
m.Post("", web.Bind(forms.StarListForm{}), starlists.Create) // 创建一个新的list
m.Get("/{listname}", starlists.GetByName) // 获取当前listname的所有repo
m.Post("/{listname}", starlists.UpdateByName) // 更新当前listname的所有repo
m.Delete("/{listname}", starlists.DeleteByName) // 删除当前listname
})

m.Group("/{username}/{reponame}", func() {
m.Get("/lists", starlists.List) // List the repo in all star lists
m.Post("/lists", starlists.UpdateListRepos) // Update the repo star lists
})

common.AddOwnerRepoGitLFSRoutes(m, optSignInIgnoreCsrf, lfsServerEnabled) // "/{username}/{reponame}/{lfs-paths}": git-lfs support

addOwnerRepoGitHTTPRouters(m) // "/{username}/{reponame}/{git-paths}": git http support
Expand Down
22 changes: 22 additions & 0 deletions services/forms/star_list_form.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package forms

import (
"net/http"

"code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/context"
"gitea.com/go-chi/binding"
)

type StarListForm struct {
Action string `binding:"Required"`
ID int64 `binding:"OmitEmpty"`
UID int64 `binding:"Required"`
Name string `binding:"Required;MaxSize(50)"`
Desc string `binding:"OmitEmpty"`
}

func (s *StarListForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
ctx := context.GetValidateContext(req)
return middleware.Validate(errs, ctx.Data, s, ctx.Locale)
}
3 changes: 2 additions & 1 deletion templates/repo/header.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@
{{end}}
>
{{svg "octicon-repo-forked"}}<span class="text not-mobile">{{ctx.Locale.Tr "repo.fork"}}</span>
<span class="ui small label">{{CountFmt .NumForks}}</span>
</a>
<a class="ui basic label" href="{{.Link}}/forks">
{{CountFmt .NumForks}}
{{svg "octicon-triangle-down"}}
</a>
</div>
<div class="ui small modal" id="fork-repo-modal">
Expand Down
9 changes: 9 additions & 0 deletions templates/repo/home_sidebar_top.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@
{{$fileSizeFields := StringUtils.Split $fileSizeFormatted " "}}
{{svg "octicon-database"}} <b>{{ctx.Locale.PrettyNumber (index $fileSizeFields 0)}}</b> {{index $fileSizeFields 1}}
</span>
<a class="flex-text-block muted" href="{{$.RepoLink}}/stars">
{{svg "octicon-star"}} {{CountFmt .Repository.NumStars}} {{ctx.Locale.Tr "repo.stars"}}
</a>
<a class="flex-text-block muted" href="{{$.RepoLink}}/watchers">
{{svg "octicon-eye"}} {{CountFmt .Repository.NumWatches}} {{ctx.Locale.Tr "repo.watchers"}}
</a>
<a class="flex-text-block muted" href="{{$.RepoLink}}/forks">
{{svg "octicon-repo-forked"}} {{CountFmt .Repository.NumForks}} {{ctx.Locale.Tr "repo.forks"}}
</a>
</div>
</div>
</div>
Expand Down
13 changes: 11 additions & 2 deletions templates/repo/star_unstar.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
<span aria-hidden="true">{{$buttonText}}</span>
<span class="ui small label">{{CountFmt .Repository.NumStars}}</span>
</button>
<a hx-boost="false" class="ui basic label" href="{{$.RepoLink}}/stars">
{{CountFmt .Repository.NumStars}}
{{if and .IsSigned (gt .ContextUser.ID 0)}}
<a class="ui basic label muted show-modal" data-modal="#choose-star-list" data-modal-modal-form.action="{{AppSubUrl}}/stars/lists">
{{svg "octicon-triangle-down"}}
</a>
{{else}}
<a class="ui basic label">
{{svg "octicon-triangle-down"}}
</a>
{{end}}
</div>
</form>

{{template "shared/star_list_dialog" .}}
3 changes: 2 additions & 1 deletion templates/repo/watch_unwatch.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
{{svg "octicon-eye"}}
<span aria-hidden="true">{{$buttonText}}</span>
<span class="ui small label">{{CountFmt .Repository.NumWatches}}</span>
</button>
<a hx-boost="false" class="ui basic label" href="{{.RepoLink}}/watchers">
{{CountFmt .Repository.NumWatches}}
{{svg "octicon-triangle-down"}}
</a>
</div>
</form>
Loading
Loading