Skip to content

Commit dd0004e

Browse files
committed
Fix bug
1 parent f24d73a commit dd0004e

File tree

11 files changed

+355
-200
lines changed

11 files changed

+355
-200
lines changed

models/issues/issue.go

Lines changed: 26 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
user_model "code.gitea.io/gitea/models/user"
1818
"code.gitea.io/gitea/modules/container"
1919
"code.gitea.io/gitea/modules/log"
20-
"code.gitea.io/gitea/modules/setting"
2120
api "code.gitea.io/gitea/modules/structs"
2221
"code.gitea.io/gitea/modules/timeutil"
2322
"code.gitea.io/gitea/modules/util"
@@ -96,7 +95,8 @@ type Issue struct {
9695
// TODO: RemoveIssueRef: see "repo/issue/branch_selector_field.tmpl"
9796
Ref string
9897

99-
PinOrder int `xorm:"DEFAULT 0"`
98+
PinOrder int `xorm:"-"`
99+
pinOrderLoaded bool `xorm:"-"`
100100

101101
DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
102102

@@ -290,6 +290,21 @@ func (issue *Issue) LoadMilestone(ctx context.Context) (err error) {
290290
return nil
291291
}
292292

293+
func (issue *Issue) LoadPinOrder(ctx context.Context) error {
294+
if issue.pinOrderLoaded || issue.PinOrder > 0 {
295+
return nil
296+
}
297+
issuePin, err := GetIssuePin(ctx, issue)
298+
if err != nil && !db.IsErrNotExist(err) {
299+
return err
300+
}
301+
issue.pinOrderLoaded = true
302+
if issuePin != nil {
303+
issue.PinOrder = issuePin.PinOrder
304+
}
305+
return nil
306+
}
307+
293308
// LoadAttributes loads the attribute of this issue.
294309
func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
295310
if err = issue.LoadRepo(ctx); err != nil {
@@ -329,6 +344,10 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
329344
return err
330345
}
331346

347+
if err = issue.LoadPinOrder(ctx); err != nil {
348+
return err
349+
}
350+
332351
if err = issue.Comments.LoadAttributes(ctx); err != nil {
333352
return err
334353
}
@@ -341,6 +360,11 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
341360
return issue.loadReactions(ctx)
342361
}
343362

363+
// IsPinned returns if a Issue is pinned
364+
func (issue *Issue) IsPinned() bool {
365+
return issue.PinOrder != 0
366+
}
367+
344368
func (issue *Issue) ResetAttributesLoaded() {
345369
issue.isLabelsLoaded = false
346370
issue.isMilestoneLoaded = false
@@ -680,190 +704,6 @@ func (issue *Issue) HasOriginalAuthor() bool {
680704
return issue.OriginalAuthor != "" && issue.OriginalAuthorID != 0
681705
}
682706

683-
var ErrIssueMaxPinReached = util.NewInvalidArgumentErrorf("the max number of pinned issues has been readched")
684-
685-
// IsPinned returns if a Issue is pinned
686-
func (issue *Issue) IsPinned() bool {
687-
return issue.PinOrder != 0
688-
}
689-
690-
// Pin pins a Issue
691-
func (issue *Issue) Pin(ctx context.Context, user *user_model.User) error {
692-
// If the Issue is already pinned, we don't need to pin it twice
693-
if issue.IsPinned() {
694-
return nil
695-
}
696-
697-
var maxPin int
698-
_, err := db.GetEngine(ctx).SQL("SELECT MAX(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ?", issue.RepoID, issue.IsPull).Get(&maxPin)
699-
if err != nil {
700-
return err
701-
}
702-
703-
// Check if the maximum allowed Pins reached
704-
if maxPin >= setting.Repository.Issue.MaxPinned {
705-
return ErrIssueMaxPinReached
706-
}
707-
708-
_, err = db.GetEngine(ctx).Table("issue").
709-
Where("id = ?", issue.ID).
710-
Update(map[string]any{
711-
"pin_order": maxPin + 1,
712-
})
713-
if err != nil {
714-
return err
715-
}
716-
717-
// Add the pin event to the history
718-
opts := &CreateCommentOptions{
719-
Type: CommentTypePin,
720-
Doer: user,
721-
Repo: issue.Repo,
722-
Issue: issue,
723-
}
724-
if _, err = CreateComment(ctx, opts); err != nil {
725-
return err
726-
}
727-
728-
return nil
729-
}
730-
731-
// UnpinIssue unpins a Issue
732-
func (issue *Issue) Unpin(ctx context.Context, user *user_model.User) error {
733-
// If the Issue is not pinned, we don't need to unpin it
734-
if !issue.IsPinned() {
735-
return nil
736-
}
737-
738-
// This sets the Pin for all Issues that come after the unpined Issue to the correct value
739-
_, err := db.GetEngine(ctx).Exec("UPDATE issue SET pin_order = pin_order - 1 WHERE repo_id = ? AND is_pull = ? AND pin_order > ?", issue.RepoID, issue.IsPull, issue.PinOrder)
740-
if err != nil {
741-
return err
742-
}
743-
744-
_, err = db.GetEngine(ctx).Table("issue").
745-
Where("id = ?", issue.ID).
746-
Update(map[string]any{
747-
"pin_order": 0,
748-
})
749-
if err != nil {
750-
return err
751-
}
752-
753-
// Add the unpin event to the history
754-
opts := &CreateCommentOptions{
755-
Type: CommentTypeUnpin,
756-
Doer: user,
757-
Repo: issue.Repo,
758-
Issue: issue,
759-
}
760-
if _, err = CreateComment(ctx, opts); err != nil {
761-
return err
762-
}
763-
764-
return nil
765-
}
766-
767-
// PinOrUnpin pins or unpins a Issue
768-
func (issue *Issue) PinOrUnpin(ctx context.Context, user *user_model.User) error {
769-
if !issue.IsPinned() {
770-
return issue.Pin(ctx, user)
771-
}
772-
773-
return issue.Unpin(ctx, user)
774-
}
775-
776-
// MovePin moves a Pinned Issue to a new Position
777-
func (issue *Issue) MovePin(ctx context.Context, newPosition int) error {
778-
// If the Issue is not pinned, we can't move them
779-
if !issue.IsPinned() {
780-
return nil
781-
}
782-
783-
if newPosition < 1 {
784-
return fmt.Errorf("The Position can't be lower than 1")
785-
}
786-
787-
dbctx, committer, err := db.TxContext(ctx)
788-
if err != nil {
789-
return err
790-
}
791-
defer committer.Close()
792-
793-
var maxPin int
794-
_, err = db.GetEngine(dbctx).SQL("SELECT MAX(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ?", issue.RepoID, issue.IsPull).Get(&maxPin)
795-
if err != nil {
796-
return err
797-
}
798-
799-
// If the new Position bigger than the current Maximum, set it to the Maximum
800-
if newPosition > maxPin+1 {
801-
newPosition = maxPin + 1
802-
}
803-
804-
// Lower the Position of all Pinned Issue that came after the current Position
805-
_, err = db.GetEngine(dbctx).Exec("UPDATE issue SET pin_order = pin_order - 1 WHERE repo_id = ? AND is_pull = ? AND pin_order > ?", issue.RepoID, issue.IsPull, issue.PinOrder)
806-
if err != nil {
807-
return err
808-
}
809-
810-
// Higher the Position of all Pinned Issues that comes after the new Position
811-
_, err = db.GetEngine(dbctx).Exec("UPDATE issue SET pin_order = pin_order + 1 WHERE repo_id = ? AND is_pull = ? AND pin_order >= ?", issue.RepoID, issue.IsPull, newPosition)
812-
if err != nil {
813-
return err
814-
}
815-
816-
_, err = db.GetEngine(dbctx).Table("issue").
817-
Where("id = ?", issue.ID).
818-
Update(map[string]any{
819-
"pin_order": newPosition,
820-
})
821-
if err != nil {
822-
return err
823-
}
824-
825-
return committer.Commit()
826-
}
827-
828-
// GetPinnedIssues returns the pinned Issues for the given Repo and type
829-
func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) (IssueList, error) {
830-
issues := make(IssueList, 0)
831-
832-
err := db.GetEngine(ctx).
833-
Table("issue").
834-
Where("repo_id = ?", repoID).
835-
And("is_pull = ?", isPull).
836-
And("pin_order > 0").
837-
OrderBy("pin_order").
838-
Find(&issues)
839-
if err != nil {
840-
return nil, err
841-
}
842-
843-
err = issues.LoadAttributes(ctx)
844-
if err != nil {
845-
return nil, err
846-
}
847-
848-
return issues, nil
849-
}
850-
851-
// IsNewPinAllowed returns if a new Issue or Pull request can be pinned
852-
func IsNewPinAllowed(ctx context.Context, repoID int64, isPull bool) (bool, error) {
853-
var maxPin int
854-
_, err := db.GetEngine(ctx).SQL("SELECT COUNT(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ? AND pin_order > 0", repoID, isPull).Get(&maxPin)
855-
if err != nil {
856-
return false, err
857-
}
858-
859-
return maxPin < setting.Repository.Issue.MaxPinned, nil
860-
}
861-
862-
// IsErrIssueMaxPinReached returns if the error is, that the User can't pin more Issues
863-
func IsErrIssueMaxPinReached(err error) bool {
864-
return err == ErrIssueMaxPinReached
865-
}
866-
867707
// InsertIssues insert issues to database
868708
func InsertIssues(ctx context.Context, issues ...*Issue) error {
869709
ctx, committer, err := db.TxContext(ctx)

models/issues/issue_list.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,36 @@ func (issues IssueList) loadTotalTrackedTimes(ctx context.Context) (err error) {
506506
return nil
507507
}
508508

509+
func (issues IssueList) LoadPinOrder(ctx context.Context) error {
510+
if len(issues) == 0 {
511+
return nil
512+
}
513+
514+
issueIDs := container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
515+
return issue.ID, issue.PinOrder == 0 && !issue.pinOrderLoaded
516+
})
517+
if len(issueIDs) == 0 {
518+
return nil
519+
}
520+
issuePins, err := GetIssuePinsByIssueIDs(ctx, issueIDs)
521+
if err != nil {
522+
return err
523+
}
524+
525+
for _, issue := range issues {
526+
if issue.PinOrder > 0 || issue.pinOrderLoaded {
527+
continue
528+
}
529+
for _, pin := range issuePins {
530+
if pin.IssueID == issue.ID {
531+
issue.PinOrder = pin.PinOrder
532+
break
533+
}
534+
}
535+
}
536+
return nil
537+
}
538+
509539
// loadAttributes loads all attributes, expect for attachments and comments
510540
func (issues IssueList) LoadAttributes(ctx context.Context) error {
511541
if _, err := issues.LoadRepositories(ctx); err != nil {

0 commit comments

Comments
 (0)