this repo has no description
1package state
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7 "sort"
8
9 "github.com/bluesky-social/indigo/atproto/syntax"
10 "tangled.org/core/api/tangled"
11 "tangled.org/core/appview/db"
12 "tangled.org/core/appview/models"
13 "tangled.org/core/appview/pages"
14 "tangled.org/core/appview/pagination"
15 "tangled.org/core/consts"
16)
17
18func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) {
19 user := s.oauth.GetUser(r)
20
21 page := pagination.FromContext(r.Context())
22
23 goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
24
25 gfiLabelDef, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", goodFirstIssueLabel))
26 if err != nil {
27 log.Println("failed to get gfi label def", err)
28 s.pages.Error500(w)
29 return
30 }
31
32 repoLabels, err := db.GetRepoLabels(s.db, db.FilterEq("label_at", goodFirstIssueLabel))
33 if err != nil {
34 log.Println("failed to get repo labels", err)
35 s.pages.Error503(w)
36 return
37 }
38
39 if len(repoLabels) == 0 {
40 s.pages.GoodFirstIssues(w, pages.GoodFirstIssuesParams{
41 LoggedInUser: user,
42 RepoGroups: []*models.RepoGroup{},
43 LabelDefs: make(map[string]*models.LabelDefinition),
44 Page: page,
45 GfiLabel: gfiLabelDef,
46 })
47 return
48 }
49
50 repoUris := make([]string, 0, len(repoLabels))
51 for _, rl := range repoLabels {
52 repoUris = append(repoUris, rl.RepoAt.String())
53 }
54
55 allIssues, err := db.GetIssuesPaginated(
56 s.db,
57 pagination.Page{
58 Limit: 500,
59 },
60 db.FilterIn("repo_at", repoUris),
61 db.FilterEq("open", 1),
62 )
63 if err != nil {
64 log.Println("failed to get issues", err)
65 s.pages.Error503(w)
66 return
67 }
68
69 var goodFirstIssues []models.Issue
70 for _, issue := range allIssues {
71 if issue.Labels.ContainsLabel(goodFirstIssueLabel) {
72 goodFirstIssues = append(goodFirstIssues, issue)
73 }
74 }
75
76 repoGroups := make(map[syntax.ATURI]*models.RepoGroup)
77 for _, issue := range goodFirstIssues {
78 if group, exists := repoGroups[issue.Repo.RepoAt()]; exists {
79 group.Issues = append(group.Issues, issue)
80 } else {
81 repoGroups[issue.Repo.RepoAt()] = &models.RepoGroup{
82 Repo: issue.Repo,
83 Issues: []models.Issue{issue},
84 }
85 }
86 }
87
88 var sortedGroups []*models.RepoGroup
89 for _, group := range repoGroups {
90 sortedGroups = append(sortedGroups, group)
91 }
92
93 sort.Slice(sortedGroups, func(i, j int) bool {
94 iIsTangled := sortedGroups[i].Repo.Did == consts.TangledDid
95 jIsTangled := sortedGroups[j].Repo.Did == consts.TangledDid
96
97 // If one is tangled and the other isn't, non-tangled comes first
98 if iIsTangled != jIsTangled {
99 return jIsTangled // true if j is tangled (i should come first)
100 }
101
102 // Both tangled or both not tangled: sort by name
103 return sortedGroups[i].Repo.Name < sortedGroups[j].Repo.Name
104 })
105
106 groupStart := page.Offset
107 groupEnd := page.Offset + page.Limit
108 if groupStart > len(sortedGroups) {
109 groupStart = len(sortedGroups)
110 }
111 if groupEnd > len(sortedGroups) {
112 groupEnd = len(sortedGroups)
113 }
114
115 paginatedGroups := sortedGroups[groupStart:groupEnd]
116
117 var allIssuesFromGroups []models.Issue
118 for _, group := range paginatedGroups {
119 allIssuesFromGroups = append(allIssuesFromGroups, group.Issues...)
120 }
121
122 var allLabelDefs []models.LabelDefinition
123 if len(allIssuesFromGroups) > 0 {
124 labelDefUris := make(map[string]bool)
125 for _, issue := range allIssuesFromGroups {
126 for labelDefUri := range issue.Labels.Inner() {
127 labelDefUris[labelDefUri] = true
128 }
129 }
130
131 uriList := make([]string, 0, len(labelDefUris))
132 for uri := range labelDefUris {
133 uriList = append(uriList, uri)
134 }
135
136 if len(uriList) > 0 {
137 allLabelDefs, err = db.GetLabelDefinitions(s.db, db.FilterIn("at_uri", uriList))
138 if err != nil {
139 log.Println("failed to fetch labels", err)
140 }
141 }
142 }
143
144 labelDefsMap := make(map[string]*models.LabelDefinition)
145 for i := range allLabelDefs {
146 labelDefsMap[allLabelDefs[i].AtUri().String()] = &allLabelDefs[i]
147 }
148
149 s.pages.GoodFirstIssues(w, pages.GoodFirstIssuesParams{
150 LoggedInUser: user,
151 RepoGroups: paginatedGroups,
152 LabelDefs: labelDefsMap,
153 Page: page,
154 GfiLabel: gfiLabelDef,
155 })
156}