package models import ( "fmt" "time" "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/api/tangled" ) type Issue struct { Id int64 Did string Rkey string RepoAt syntax.ATURI IssueId int Created time.Time Edited *time.Time Deleted *time.Time Title string Body string Open bool Mentions []syntax.DID References []syntax.ATURI // optionally, populate this when querying for reverse mappings // like comment counts, parent repo etc. Comments []Comment Labels LabelState Repo *Repo } func (i *Issue) AtUri() syntax.ATURI { return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.Did, tangled.RepoIssueNSID, i.Rkey)) } func (i *Issue) AsRecord() tangled.RepoIssue { mentions := make([]string, len(i.Mentions)) for i, did := range i.Mentions { mentions[i] = string(did) } references := make([]string, len(i.References)) for i, uri := range i.References { references[i] = string(uri) } repoAtStr := i.RepoAt.String() rec := tangled.RepoIssue{ Repo: &repoAtStr, Title: i.Title, Body: &i.Body, Mentions: mentions, References: references, CreatedAt: i.Created.Format(time.RFC3339), } if i.Repo != nil && i.Repo.RepoDid != "" { rec.RepoDid = &i.Repo.RepoDid } return rec } func (i *Issue) State() string { if i.Open { return "open" } return "closed" } func (i *Issue) Participants() []string { participantSet := make(map[string]struct{}) participants := []string{} addParticipant := func(did string) { if _, exists := participantSet[did]; !exists { participantSet[did] = struct{}{} participants = append(participants, did) } } addParticipant(i.Did) for _, c := range i.Comments { addParticipant(c.Did.String()) } return participants } func IssueFromRecord(did, rkey string, record tangled.RepoIssue) Issue { created, err := time.Parse(time.RFC3339, record.CreatedAt) if err != nil { created = time.Now() } body := "" if record.Body != nil { body = *record.Body } var repoAt syntax.ATURI if record.Repo != nil { repoAt = syntax.ATURI(*record.Repo) } return Issue{ RepoAt: repoAt, Did: did, Rkey: rkey, Created: created, Title: record.Title, Body: body, Open: true, // new issues are open by default } }