+5
appview/models/repo.go
+5
appview/models/repo.go
+12
appview/pages/pages.go
+12
appview/pages/pages.go
···
312
return p.execute("timeline/timeline", w, params)
313
}
314
315
+
type GoodFirstIssuesParams struct {
316
+
LoggedInUser *oauth.User
317
+
Issues []models.Issue
318
+
RepoGroups []*models.RepoGroup
319
+
LabelDefs map[string]*models.LabelDefinition
320
+
Page pagination.Page
321
+
}
322
+
323
+
func (p *Pages) GoodFirstIssues(w io.Writer, params GoodFirstIssuesParams) error {
324
+
return p.execute("goodfirstissues/index", w, params)
325
+
}
326
+
327
type UserProfileSettingsParams struct {
328
LoggedInUser *oauth.User
329
Tabs []map[string]any
+138
appview/state/gfi.go
+138
appview/state/gfi.go
···
···
1
+
package state
2
+
3
+
import (
4
+
"fmt"
5
+
"log"
6
+
"net/http"
7
+
"sort"
8
+
9
+
"tangled.org/core/api/tangled"
10
+
"tangled.org/core/appview/db"
11
+
"tangled.org/core/appview/models"
12
+
"tangled.org/core/appview/pages"
13
+
"tangled.org/core/appview/pagination"
14
+
"tangled.org/core/consts"
15
+
)
16
+
17
+
func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) {
18
+
user := s.oauth.GetUser(r)
19
+
20
+
page, ok := r.Context().Value("page").(pagination.Page)
21
+
if !ok {
22
+
page = pagination.FirstPage()
23
+
}
24
+
25
+
goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
26
+
27
+
repoLabels, err := db.GetRepoLabels(s.db, db.FilterEq("label_at", goodFirstIssueLabel))
28
+
if err != nil {
29
+
log.Println("failed to get repo labels", err)
30
+
s.pages.Error503(w)
31
+
return
32
+
}
33
+
34
+
if len(repoLabels) == 0 {
35
+
s.pages.GoodFirstIssues(w, pages.GoodFirstIssuesParams{
36
+
LoggedInUser: user,
37
+
RepoGroups: []*models.RepoGroup{},
38
+
LabelDefs: make(map[string]*models.LabelDefinition),
39
+
Page: page,
40
+
})
41
+
return
42
+
}
43
+
44
+
repoUris := make([]string, 0, len(repoLabels))
45
+
for _, rl := range repoLabels {
46
+
repoUris = append(repoUris, rl.RepoAt.String())
47
+
}
48
+
49
+
allIssues, err := db.GetIssues(
50
+
s.db,
51
+
db.FilterIn("repo_at", repoUris),
52
+
db.FilterEq("open", 1),
53
+
)
54
+
if err != nil {
55
+
log.Println("failed to get issues", err)
56
+
s.pages.Error503(w)
57
+
return
58
+
}
59
+
60
+
var goodFirstIssues []models.Issue
61
+
for _, issue := range allIssues {
62
+
if issue.Labels.ContainsLabel(goodFirstIssueLabel) {
63
+
goodFirstIssues = append(goodFirstIssues, issue)
64
+
}
65
+
}
66
+
67
+
repoGroups := make(map[string]*models.RepoGroup)
68
+
for _, issue := range goodFirstIssues {
69
+
repoKey := fmt.Sprintf("%s/%s", issue.Repo.Did, issue.Repo.Name)
70
+
if group, exists := repoGroups[repoKey]; exists {
71
+
group.Issues = append(group.Issues, issue)
72
+
} else {
73
+
repoGroups[repoKey] = &models.RepoGroup{
74
+
Repo: issue.Repo,
75
+
Issues: []models.Issue{issue},
76
+
}
77
+
}
78
+
}
79
+
80
+
var sortedGroups []*models.RepoGroup
81
+
for _, group := range repoGroups {
82
+
sortedGroups = append(sortedGroups, group)
83
+
}
84
+
85
+
sort.Slice(sortedGroups, func(i, j int) bool {
86
+
return sortedGroups[i].Repo.Name < sortedGroups[j].Repo.Name
87
+
})
88
+
89
+
groupStart := page.Offset
90
+
groupEnd := page.Offset + page.Limit
91
+
if groupStart > len(sortedGroups) {
92
+
groupStart = len(sortedGroups)
93
+
}
94
+
if groupEnd > len(sortedGroups) {
95
+
groupEnd = len(sortedGroups)
96
+
}
97
+
98
+
paginatedGroups := sortedGroups[groupStart:groupEnd]
99
+
100
+
var allIssuesFromGroups []models.Issue
101
+
for _, group := range paginatedGroups {
102
+
allIssuesFromGroups = append(allIssuesFromGroups, group.Issues...)
103
+
}
104
+
105
+
var allLabelDefs []models.LabelDefinition
106
+
if len(allIssuesFromGroups) > 0 {
107
+
labelDefUris := make(map[string]bool)
108
+
for _, issue := range allIssuesFromGroups {
109
+
for labelDefUri := range issue.Labels.Inner() {
110
+
labelDefUris[labelDefUri] = true
111
+
}
112
+
}
113
+
114
+
uriList := make([]string, 0, len(labelDefUris))
115
+
for uri := range labelDefUris {
116
+
uriList = append(uriList, uri)
117
+
}
118
+
119
+
if len(uriList) > 0 {
120
+
allLabelDefs, err = db.GetLabelDefinitions(s.db, db.FilterIn("at_uri", uriList))
121
+
if err != nil {
122
+
log.Println("failed to fetch labels", err)
123
+
}
124
+
}
125
+
}
126
+
127
+
labelDefsMap := make(map[string]*models.LabelDefinition)
128
+
for i := range allLabelDefs {
129
+
labelDefsMap[allLabelDefs[i].AtUri().String()] = &allLabelDefs[i]
130
+
}
131
+
132
+
s.pages.GoodFirstIssues(w, pages.GoodFirstIssuesParams{
133
+
LoggedInUser: user,
134
+
RepoGroups: paginatedGroups,
135
+
LabelDefs: labelDefsMap,
136
+
Page: page,
137
+
})
138
+
}
+2
appview/state/router.go
+2
appview/state/router.go