mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in NOTICE, alongside LICENSE. The header lint accepts any copyright line above the SPDX line, so it no longer demands an upstream one. Co-authored-by: Hanzo Dev <[email protected]>
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package issues
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/hanzoai/git/models/db"
|
|
repo_model "github.com/hanzoai/git/models/repo"
|
|
)
|
|
|
|
// IssueUser represents an issue-user relation.
|
|
type IssueUser struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
UID int64 `xorm:"INDEX unique(uid_to_issue)"` // User ID.
|
|
IssueID int64 `xorm:"INDEX unique(uid_to_issue)"`
|
|
IsRead bool
|
|
IsMentioned bool
|
|
}
|
|
|
|
func init() {
|
|
db.RegisterModel(new(IssueUser))
|
|
}
|
|
|
|
// NewIssueUsers inserts an issue related users
|
|
func NewIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error {
|
|
assignees, err := repo_model.GetRepoAssignees(ctx, repo)
|
|
if err != nil {
|
|
return fmt.Errorf("getAssignees: %w", err)
|
|
}
|
|
|
|
// Poster can be anyone, append later if not one of assignees.
|
|
isPosterAssignee := false
|
|
|
|
// Leave a seat for poster itself to append later, but if poster is one of assignee
|
|
// and just waste 1 unit is cheaper than re-allocate memory once.
|
|
issueUsers := make([]*IssueUser, 0, len(assignees)+1)
|
|
for _, assignee := range assignees {
|
|
issueUsers = append(issueUsers, &IssueUser{
|
|
IssueID: issue.ID,
|
|
UID: assignee.ID,
|
|
})
|
|
isPosterAssignee = isPosterAssignee || assignee.ID == issue.PosterID
|
|
}
|
|
if !isPosterAssignee {
|
|
issueUsers = append(issueUsers, &IssueUser{
|
|
IssueID: issue.ID,
|
|
UID: issue.PosterID,
|
|
})
|
|
}
|
|
|
|
return db.Insert(ctx, issueUsers)
|
|
}
|
|
|
|
// UpdateIssueUserByRead updates issue-user relation for reading.
|
|
func UpdateIssueUserByRead(ctx context.Context, uid, issueID int64) error {
|
|
_, err := db.GetEngine(ctx).Exec("UPDATE `issue_user` SET is_read=? WHERE uid=? AND issue_id=?", true, uid, issueID)
|
|
return err
|
|
}
|
|
|
|
// UpdateIssueUsersByMentions updates issue-user pairs by mentioning.
|
|
func UpdateIssueUsersByMentions(ctx context.Context, issueID int64, uids []int64) error {
|
|
for _, uid := range uids {
|
|
iu := &IssueUser{
|
|
UID: uid,
|
|
IssueID: issueID,
|
|
}
|
|
has, err := db.GetEngine(ctx).Get(iu)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
iu.IsMentioned = true
|
|
if has {
|
|
_, err = db.GetEngine(ctx).ID(iu.ID).Cols("is_mentioned").Update(iu)
|
|
} else {
|
|
_, err = db.GetEngine(ctx).Insert(iu)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetIssueMentionIDs returns all mentioned user IDs of an issue.
|
|
func GetIssueMentionIDs(ctx context.Context, issueID int64) ([]int64, error) {
|
|
var ids []int64
|
|
return ids, db.GetEngine(ctx).Table(IssueUser{}).
|
|
Where("issue_id=?", issueID).
|
|
And("is_mentioned=?", true).
|
|
Select("uid").
|
|
Find(&ids)
|
|
}
|