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