tangled
alpha
login
or
join now
tjh.dev
/
core
forked from
tangled.org/core
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
group profile timeline by month
oppi.li
11 months ago
0158248f
5a9057f4
+401
-90
7 changed files
expand all
collapse all
unified
split
appview
db
issues.go
profile.go
pulls.go
repos.go
pages
pages.go
templates
user
profile.html
state
profile.go
+48
-18
appview/db/issues.go
···
12
12
OwnerDid string
13
13
IssueId int
14
14
IssueAt string
15
15
-
Created *time.Time
15
15
+
Created time.Time
16
16
Title string
17
17
Body string
18
18
Open bool
19
19
+
20
20
+
// optionally, populate this when querying for reverse mappings
21
21
+
// like comment counts, parent repo etc.
19
22
Metadata *IssueMetadata
20
23
}
21
24
22
25
type IssueMetadata struct {
23
26
CommentCount int
27
27
+
Repo *Repo
24
28
// labels, assignee etc.
25
29
}
26
30
···
143
147
if err != nil {
144
148
return nil, err
145
149
}
146
146
-
issue.Created = &createdTime
150
150
+
issue.Created = createdTime
147
151
issue.Metadata = &metadata
148
152
149
153
issues = append(issues, issue)
···
156
160
return issues, nil
157
161
}
158
162
159
159
-
func GetIssuesByOwnerDid(e Execer, ownerDid string) ([]Issue, error) {
163
163
+
// timeframe here is directly passed into the sql query filter, and any
164
164
+
// timeframe in the past should be negative; e.g.: "-3 months"
165
165
+
func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, error) {
160
166
var issues []Issue
161
167
162
168
rows, err := e.Query(
···
168
174
i.title,
169
175
i.body,
170
176
i.open,
171
171
-
count(c.id)
177
177
+
r.did,
178
178
+
r.name,
179
179
+
r.knot,
180
180
+
r.rkey,
181
181
+
r.created
172
182
from
173
183
issues i
174
174
-
left join
175
175
-
comments c on i.repo_at = c.repo_at and i.issue_id = c.issue_id
184
184
+
join
185
185
+
repos r on i.repo_at = r.at_uri
176
186
where
177
177
-
i.owner_did = ?
178
178
-
group by
179
179
-
i.id, i.owner_did, i.repo_at, i.issue_id, i.created, i.title, i.body, i.open
187
187
+
i.owner_did = ? and i.created >= date ('now', ?)
180
188
order by
181
189
i.created desc`,
182
182
-
ownerDid)
190
190
+
ownerDid, timeframe)
183
191
if err != nil {
184
192
return nil, err
185
193
}
···
187
195
188
196
for rows.Next() {
189
197
var issue Issue
190
190
-
var createdAt string
191
191
-
var metadata IssueMetadata
192
192
-
err := rows.Scan(&issue.OwnerDid, &issue.RepoAt, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount)
198
198
+
var issueCreatedAt, repoCreatedAt string
199
199
+
var repo Repo
200
200
+
err := rows.Scan(
201
201
+
&issue.OwnerDid,
202
202
+
&issue.RepoAt,
203
203
+
&issue.IssueId,
204
204
+
&issueCreatedAt,
205
205
+
&issue.Title,
206
206
+
&issue.Body,
207
207
+
&issue.Open,
208
208
+
&repo.Did,
209
209
+
&repo.Name,
210
210
+
&repo.Knot,
211
211
+
&repo.Rkey,
212
212
+
&repoCreatedAt,
213
213
+
)
193
214
if err != nil {
194
215
return nil, err
195
216
}
196
217
197
197
-
createdTime, err := time.Parse(time.RFC3339, createdAt)
218
218
+
issueCreatedTime, err := time.Parse(time.RFC3339, issueCreatedAt)
219
219
+
if err != nil {
220
220
+
return nil, err
221
221
+
}
222
222
+
issue.Created = issueCreatedTime
223
223
+
224
224
+
repoCreatedTime, err := time.Parse(time.RFC3339, repoCreatedAt)
198
225
if err != nil {
199
226
return nil, err
200
227
}
201
201
-
issue.Created = &createdTime
202
202
-
issue.Metadata = &metadata
228
228
+
repo.Created = repoCreatedTime
229
229
+
230
230
+
issue.Metadata = &IssueMetadata{
231
231
+
Repo: &repo,
232
232
+
}
203
233
204
234
issues = append(issues, issue)
205
235
}
···
226
256
if err != nil {
227
257
return nil, err
228
258
}
229
229
-
issue.Created = &createdTime
259
259
+
issue.Created = createdTime
230
260
231
261
return &issue, nil
232
262
}
···
246
276
if err != nil {
247
277
return nil, nil, err
248
278
}
249
249
-
issue.Created = &createdTime
279
279
+
issue.Created = createdTime
250
280
251
281
comments, err := GetComments(e, repoAt, issueId)
252
282
if err != nil {
+117
-48
appview/db/profile.go
···
1
1
package db
2
2
3
3
import (
4
4
+
"encoding/json"
4
5
"fmt"
5
5
-
"sort"
6
6
"time"
7
7
)
8
8
9
9
-
type ProfileTimelineEvent struct {
10
10
-
EventAt time.Time
11
11
-
Type string
12
12
-
*Issue
13
13
-
*Pull
14
14
-
*Repo
9
9
+
type RepoEvent struct {
10
10
+
Repo *Repo
11
11
+
Source *Repo
12
12
+
}
13
13
+
14
14
+
type ProfileTimeline struct {
15
15
+
ByMonth []ByMonth
16
16
+
}
17
17
+
18
18
+
type ByMonth struct {
19
19
+
RepoEvents []RepoEvent
20
20
+
IssueEvents IssueEvents
21
21
+
PullEvents PullEvents
22
22
+
}
23
23
+
24
24
+
type IssueEvents struct {
25
25
+
Items []*Issue
26
26
+
}
27
27
+
28
28
+
type IssueEventStats struct {
29
29
+
Open int
30
30
+
Closed int
31
31
+
}
32
32
+
33
33
+
func (i IssueEvents) Stats() IssueEventStats {
34
34
+
var open, closed int
35
35
+
for _, issue := range i.Items {
36
36
+
if issue.Open {
37
37
+
open += 1
38
38
+
} else {
39
39
+
closed += 1
40
40
+
}
41
41
+
}
42
42
+
43
43
+
return IssueEventStats{
44
44
+
Open: open,
45
45
+
Closed: closed,
46
46
+
}
47
47
+
}
48
48
+
49
49
+
type PullEvents struct {
50
50
+
Items []*Pull
51
51
+
}
52
52
+
53
53
+
func (p PullEvents) Stats() PullEventStats {
54
54
+
var open, merged, closed int
55
55
+
for _, pull := range p.Items {
56
56
+
switch pull.State {
57
57
+
case PullOpen:
58
58
+
open += 1
59
59
+
case PullMerged:
60
60
+
merged += 1
61
61
+
case PullClosed:
62
62
+
closed += 1
63
63
+
}
64
64
+
}
65
65
+
66
66
+
return PullEventStats{
67
67
+
Open: open,
68
68
+
Merged: merged,
69
69
+
Closed: closed,
70
70
+
}
71
71
+
}
15
72
16
16
-
// optional: populate only if Repo is a fork
17
17
-
Source *Repo
73
73
+
type PullEventStats struct {
74
74
+
Closed int
75
75
+
Open int
76
76
+
Merged int
18
77
}
19
78
20
20
-
func MakeProfileTimeline(e Execer, forDid string) ([]ProfileTimelineEvent, error) {
21
21
-
timeline := []ProfileTimelineEvent{}
22
22
-
limit := 30
79
79
+
const TimeframeMonths = 3
80
80
+
81
81
+
func MakeProfileTimeline(e Execer, forDid string) (*ProfileTimeline, error) {
82
82
+
timeline := ProfileTimeline{
83
83
+
ByMonth: make([]ByMonth, TimeframeMonths),
84
84
+
}
85
85
+
currentMonth := time.Now().Month()
86
86
+
timeframe := fmt.Sprintf("-%d months", TimeframeMonths)
23
87
24
24
-
pulls, err := GetPullsByOwnerDid(e, forDid)
88
88
+
pulls, err := GetPullsByOwnerDid(e, forDid, timeframe)
25
89
if err != nil {
26
26
-
return timeline, fmt.Errorf("error getting pulls by owner did: %w", err)
90
90
+
return nil, fmt.Errorf("error getting pulls by owner did: %w", err)
27
91
}
28
92
93
93
+
// group pulls by month
29
94
for _, pull := range pulls {
30
30
-
repo, err := GetRepoByAtUri(e, string(pull.RepoAt))
31
31
-
if err != nil {
32
32
-
return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
95
95
+
pullMonth := pull.Created.Month()
96
96
+
97
97
+
if currentMonth-pullMonth > TimeframeMonths {
98
98
+
// shouldn't happen; but times are weird
99
99
+
continue
33
100
}
34
101
35
35
-
timeline = append(timeline, ProfileTimelineEvent{
36
36
-
EventAt: pull.Created,
37
37
-
Type: "pull",
38
38
-
Pull: &pull,
39
39
-
Repo: repo,
40
40
-
})
102
102
+
idx := currentMonth - pullMonth
103
103
+
items := &timeline.ByMonth[idx].PullEvents.Items
104
104
+
105
105
+
*items = append(*items, &pull)
41
106
}
42
107
43
43
-
issues, err := GetIssuesByOwnerDid(e, forDid)
108
108
+
issues, err := GetIssuesByOwnerDid(e, forDid, timeframe)
44
109
if err != nil {
45
45
-
return timeline, fmt.Errorf("error getting issues by owner did: %w", err)
110
110
+
return nil, fmt.Errorf("error getting issues by owner did: %w", err)
46
111
}
47
112
48
113
for _, issue := range issues {
49
49
-
repo, err := GetRepoByAtUri(e, string(issue.RepoAt))
50
50
-
if err != nil {
51
51
-
return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
114
114
+
issueMonth := issue.Created.Month()
115
115
+
116
116
+
if currentMonth-issueMonth > TimeframeMonths {
117
117
+
// shouldn't happen; but times are weird
118
118
+
continue
52
119
}
53
120
54
54
-
timeline = append(timeline, ProfileTimelineEvent{
55
55
-
EventAt: *issue.Created,
56
56
-
Type: "issue",
57
57
-
Issue: &issue,
58
58
-
Repo: repo,
59
59
-
})
121
121
+
idx := currentMonth - issueMonth
122
122
+
items := &timeline.ByMonth[idx].IssueEvents.Items
123
123
+
124
124
+
*items = append(*items, &issue)
60
125
}
61
126
62
127
repos, err := GetAllReposByDid(e, forDid)
63
128
if err != nil {
64
64
-
return timeline, fmt.Errorf("error getting all repos by did: %w", err)
129
129
+
return nil, fmt.Errorf("error getting all repos by did: %w", err)
65
130
}
66
131
67
132
for _, repo := range repos {
133
133
+
// TODO: get this in the original query; requires COALESCE because nullable
68
134
var sourceRepo *Repo
69
135
if repo.Source != "" {
70
136
sourceRepo, err = GetRepoByAtUri(e, repo.Source)
···
73
139
}
74
140
}
75
141
76
76
-
timeline = append(timeline, ProfileTimelineEvent{
77
77
-
EventAt: repo.Created,
78
78
-
Type: "repo",
79
79
-
Repo: &repo,
80
80
-
Source: sourceRepo,
142
142
+
repoMonth := repo.Created.Month()
143
143
+
144
144
+
if currentMonth-repoMonth > TimeframeMonths {
145
145
+
// shouldn't happen; but times are weird
146
146
+
continue
147
147
+
}
148
148
+
149
149
+
idx := currentMonth - repoMonth
150
150
+
151
151
+
items := &timeline.ByMonth[idx].RepoEvents
152
152
+
*items = append(*items, RepoEvent{
153
153
+
Repo: &repo,
154
154
+
Source: sourceRepo,
81
155
})
82
156
}
83
157
84
84
-
sort.Slice(timeline, func(i, j int) bool {
85
85
-
return timeline[i].EventAt.After(timeline[j].EventAt)
86
86
-
})
87
87
-
88
88
-
if len(timeline) > limit {
89
89
-
timeline = timeline[:limit]
90
90
-
}
158
158
+
x, _ := json.MarshalIndent(timeline, "", "\t")
159
159
+
fmt.Println(string(x))
91
160
92
92
-
return timeline, nil
161
161
+
return &timeline, nil
93
162
}
+40
-14
appview/db/pulls.go
···
64
64
// meta
65
65
Created time.Time
66
66
PullSource *PullSource
67
67
+
68
68
+
// optionally, populate this when querying for reverse mappings
69
69
+
Repo *Repo
67
70
}
68
71
69
72
type PullSource struct {
···
522
525
return &pull, nil
523
526
}
524
527
525
525
-
func GetPullsByOwnerDid(e Execer, did string) ([]Pull, error) {
528
528
+
// timeframe here is directly passed into the sql query filter, and any
529
529
+
// timeframe in the past should be negative; e.g.: "-3 months"
530
530
+
func GetPullsByOwnerDid(e Execer, did, timeframe string) ([]Pull, error) {
526
531
var pulls []Pull
527
532
528
533
rows, err := e.Query(`
529
534
select
530
530
-
owner_did,
531
531
-
repo_at,
532
532
-
pull_id,
533
533
-
created,
534
534
-
title,
535
535
-
state
535
535
+
p.owner_did,
536
536
+
p.repo_at,
537
537
+
p.pull_id,
538
538
+
p.created,
539
539
+
p.title,
540
540
+
p.state,
541
541
+
r.did,
542
542
+
r.name,
543
543
+
r.knot,
544
544
+
r.rkey,
545
545
+
r.created
536
546
from
537
537
-
pulls
547
547
+
pulls p
548
548
+
join
549
549
+
repos r on p.repo_at = r.at_uri
538
550
where
539
539
-
owner_did = ?
551
551
+
p.owner_did = ? and p.created >= date ('now', ?)
540
552
order by
541
541
-
created desc`, did)
553
553
+
p.created desc`, did, timeframe)
542
554
if err != nil {
543
555
return nil, err
544
556
}
···
546
558
547
559
for rows.Next() {
548
560
var pull Pull
549
549
-
var createdAt string
561
561
+
var repo Repo
562
562
+
var pullCreatedAt, repoCreatedAt string
550
563
err := rows.Scan(
551
564
&pull.OwnerDid,
552
565
&pull.RepoAt,
553
566
&pull.PullId,
554
554
-
&createdAt,
567
567
+
&pullCreatedAt,
555
568
&pull.Title,
556
569
&pull.State,
570
570
+
&repo.Did,
571
571
+
&repo.Name,
572
572
+
&repo.Knot,
573
573
+
&repo.Rkey,
574
574
+
&repoCreatedAt,
557
575
)
558
576
if err != nil {
559
577
return nil, err
560
578
}
561
579
562
562
-
createdTime, err := time.Parse(time.RFC3339, createdAt)
580
580
+
pullCreatedTime, err := time.Parse(time.RFC3339, pullCreatedAt)
563
581
if err != nil {
564
582
return nil, err
565
583
}
566
566
-
pull.Created = createdTime
584
584
+
pull.Created = pullCreatedTime
585
585
+
586
586
+
repoCreatedTime, err := time.Parse(time.RFC3339, repoCreatedAt)
587
587
+
if err != nil {
588
588
+
return nil, err
589
589
+
}
590
590
+
repo.Created = repoCreatedTime
591
591
+
592
592
+
pull.Repo = &repo
567
593
568
594
pulls = append(pulls, pull)
569
595
}
+3
-1
appview/db/repos.go
···
77
77
where
78
78
r.did = ?
79
79
group by
80
80
-
r.at_uri`, did)
80
80
+
r.at_uri
81
81
+
order by r.created desc`,
82
82
+
did)
81
83
if err != nil {
82
84
return nil, err
83
85
}
+3
-2
appview/pages/pages.go
···
178
178
CollaboratingRepos []db.Repo
179
179
ProfileStats ProfileStats
180
180
FollowStatus db.FollowStatus
181
181
-
DidHandleMap map[string]string
182
181
AvatarUri string
183
183
-
ProfileTimeline []db.ProfileTimelineEvent
182
182
+
ProfileTimeline *db.ProfileTimeline
183
183
+
184
184
+
DidHandleMap map[string]string
184
185
}
185
186
186
187
type ProfileStats struct {
+179
-2
appview/pages/templates/user/profile.html
···
9
9
{{ block "ownRepos" . }}{{ end }}
10
10
{{ block "collaboratingRepos" . }}{{ end }}
11
11
</div>
12
12
-
13
12
<div class="md:col-span-2 order-3 md:order-3">
14
14
-
{{ block "profileTimeline" . }}{{ end }}
13
13
+
{{ block "profileTimeline2" . }}{{ end }}
15
14
</div>
16
15
</div>
17
16
{{ end }}
18
17
18
18
+
{{ define "profileTimeline2" }}
19
19
+
<p class="text-sm font-bold py-2 dark:text-white">ACTIVITY</p>
20
20
+
<div class="flex flex-col gap-6 relative">
21
21
+
{{ with .ProfileTimeline }}
22
22
+
{{ range $idx, $byMonth := .ByMonth }}
23
23
+
{{ with $byMonth }}
24
24
+
<div>
25
25
+
{{ if eq $idx 0 }}
26
26
+
<p class="text-sm font-bold py-2 dark:text-white">This month</p>
27
27
+
{{ else }}
28
28
+
{{ $s := "s" }}
29
29
+
{{ if eq $idx 1 }}
30
30
+
{{ $s = "" }}
31
31
+
{{ end }}
32
32
+
<p class="text-sm font-bold py-2 dark:text-white">{{$idx}} month{{$s}} ago</p>
33
33
+
{{ end }}
34
34
+
35
35
+
<div class="flex flex-col gap-4">
36
36
+
{{ block "repoEvents" (list .RepoEvents $.DidHandleMap) }} {{ end }}
37
37
+
{{ block "issueEvents" (list .IssueEvents $.DidHandleMap) }} {{ end }}
38
38
+
{{ block "pullEvents" (list .PullEvents $.DidHandleMap) }} {{ end }}
39
39
+
</div>
40
40
+
</div>
41
41
+
42
42
+
{{ end }}
43
43
+
{{ else }}
44
44
+
<p class="dark:text-white">This user does not have any activity yet.</p>
45
45
+
{{ end }}
46
46
+
{{ end }}
47
47
+
</div>
48
48
+
{{ end }}
49
49
+
50
50
+
{{ define "repoEvents" }}
51
51
+
{{ $items := index . 0 }}
52
52
+
{{ $handleMap := index . 1 }}
53
53
+
54
54
+
{{ if gt (len $items) 0 }}
55
55
+
<details open>
56
56
+
<summary class="list-none cursor-pointer">
57
57
+
<div class="flex items-center gap-2">
58
58
+
{{ i "unfold-vertical" "w-4 h-4" }}
59
59
+
created {{ len $items }} repositories
60
60
+
</div>
61
61
+
</summary>
62
62
+
<div class="p-2 pl-8 text-sm flex flex-col gap-3">
63
63
+
{{ range $items }}
64
64
+
<div class="flex flex-wrap items-center gap-2">
65
65
+
<span class="text-gray-500 dark:text-gray-400">
66
66
+
{{ if .Source }}
67
67
+
{{ i "git-fork" "w-4 h-4" }}
68
68
+
{{ else }}
69
69
+
{{ i "book-plus" "w-4 h-4" }}
70
70
+
{{ end }}
71
71
+
</span>
72
72
+
<a href="/{{ index $handleMap .Repo.Did }}/{{ .Repo.Name }}" class="no-underline hover:underline">
73
73
+
{{- .Repo.Name -}}
74
74
+
</a>
75
75
+
<time class="text-gray-700 dark:text-gray-400 text-xs ml-2">{{ .Repo.Created | shortTimeFmt }}</time>
76
76
+
</div>
77
77
+
{{ end }}
78
78
+
</div>
79
79
+
</details>
80
80
+
{{ end }}
81
81
+
{{ end }}
82
82
+
83
83
+
{{ define "issueEvents" }}
84
84
+
{{ $i := index . 0 }}
85
85
+
{{ $items := $i.Items }}
86
86
+
{{ $stats := $i.Stats }}
87
87
+
{{ $handleMap := index . 1 }}
88
88
+
89
89
+
{{ if gt (len $items) 0 }}
90
90
+
<details open>
91
91
+
<summary class="list-none cursor-pointer">
92
92
+
<div class="flex items-center gap-2">
93
93
+
{{ i "unfold-vertical" "w-4 h-4" }}
94
94
+
<span>
95
95
+
created {{ len $items }} issues
96
96
+
</span>
97
97
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-green-600 dark:bg-green-700">
98
98
+
{{$stats.Open}} open
99
99
+
</span>
100
100
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-gray-800 dark:bg-gray-700">
101
101
+
{{$stats.Closed}} closed
102
102
+
</span>
103
103
+
</div>
104
104
+
</summary>
105
105
+
<div class="p-2 pl-8 text-sm flex flex-col gap-3">
106
106
+
{{ range $items }}
107
107
+
{{ $repoOwner := index $handleMap .Metadata.Repo.Did }}
108
108
+
{{ $repoName := .Metadata.Repo.Name }}
109
109
+
{{ $repoUrl := printf "%s/%s" $repoOwner $repoName }}
110
110
+
111
111
+
<div class="flex flex-wrap items-center gap-2 text-gray-600 dark:text-gray-300">
112
112
+
{{ if .Open }}
113
113
+
<span class="text-green-600 dark:text-green-500">
114
114
+
{{ i "circle-dot" "w-4 h-4" }}
115
115
+
</span>
116
116
+
{{ else }}
117
117
+
<span class="text-gray-500 dark:text-gray-400">
118
118
+
{{ i "ban" "w-4 h-4" }}
119
119
+
</span>
120
120
+
{{ end }}
121
121
+
<a href="/{{$repoUrl}}/issues/{{ .IssueId }}" class="no-underline hover:underline">
122
122
+
<span class="text-gray-500 dark:text-gray-400">#{{ .IssueId }}</span>
123
123
+
{{ .Title -}}
124
124
+
</a>
125
125
+
on
126
126
+
<a href="/{{$repoUrl}}" class="no-underline hover:underline">
127
127
+
{{$repoUrl}}
128
128
+
</a>
129
129
+
<time class="text-gray-700 dark:text-gray-400 text-xs ml-2">{{ .Created | shortTimeFmt }}</time>
130
130
+
</p>
131
131
+
{{ end }}
132
132
+
</div>
133
133
+
</details>
134
134
+
{{ end }}
135
135
+
{{ end }}
136
136
+
137
137
+
{{ define "pullEvents" }}
138
138
+
{{ $i := index . 0 }}
139
139
+
{{ $items := $i.Items }}
140
140
+
{{ $stats := $i.Stats }}
141
141
+
{{ $handleMap := index . 1 }}
142
142
+
{{ if gt (len $items) 0 }}
143
143
+
<details open>
144
144
+
<summary class="list-none cursor-pointer">
145
145
+
<div class="flex items-center gap-2">
146
146
+
{{ i "unfold-vertical" "w-4 h-4" }}
147
147
+
<span>
148
148
+
created {{ len $items }} pull requests
149
149
+
</span>
150
150
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-green-600 dark:bg-green-700">
151
151
+
{{$stats.Open}} open
152
152
+
</span>
153
153
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-purple-600 dark:bg-purple-700">
154
154
+
{{$stats.Merged}} merged
155
155
+
</span>
156
156
+
<span class="px-2 py-1/2 text-sm rounded-sm text-black dark:text-white bg-gray-50 dark:bg-gray-700 ">
157
157
+
{{$stats.Closed}} closed
158
158
+
</span>
159
159
+
</div>
160
160
+
</summary>
161
161
+
<div class="p-2 pl-8 text-sm flex flex-col gap-3">
162
162
+
{{ range $items }}
163
163
+
{{ $repoOwner := index $handleMap .Repo.Did }}
164
164
+
{{ $repoName := .Repo.Name }}
165
165
+
{{ $repoUrl := printf "%s/%s" $repoOwner $repoName }}
166
166
+
167
167
+
<div class="flex flex-wrap items-center gap-2 text-gray-600 dark:text-gray-300">
168
168
+
{{ if .State.IsOpen }}
169
169
+
<span class="text-green-600 dark:text-green-500">
170
170
+
{{ i "git-pull-request" "w-4 h-4" }}
171
171
+
</span>
172
172
+
{{ else if .State.IsMerged }}
173
173
+
<span class="text-purple-600 dark:text-purple-500">
174
174
+
{{ i "git-merge" "w-4 h-4" }}
175
175
+
</span>
176
176
+
{{ else }}
177
177
+
<span class="text-gray-600 dark:text-gray-300">
178
178
+
{{ i "git-pull-request-closed" "w-4 h-4" }}
179
179
+
</span>
180
180
+
{{ end }}
181
181
+
<a href="/{{$repoUrl}}/pulls/{{ .PullId }}" class="no-underline hover:underline">
182
182
+
<span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span>
183
183
+
{{ .Title -}}
184
184
+
</a>
185
185
+
on
186
186
+
<a href="/{{$repoUrl}}" class="no-underline hover:underline">
187
187
+
{{$repoUrl}}
188
188
+
</a>
189
189
+
<time class="text-gray-700 dark:text-gray-400 text-xs ml-2">{{ .Created | shortTimeFmt }}</time>
190
190
+
</p>
191
191
+
{{ end }}
192
192
+
</div>
193
193
+
</details>
194
194
+
{{ end }}
195
195
+
{{ end }}
19
196
20
197
{{ define "profileTimeline" }}
21
198
<div class="flex flex-col gap-3 relative">
+11
-5
appview/state/profile.go
···
43
43
for _, r := range collaboratingRepos {
44
44
didsToResolve = append(didsToResolve, r.Did)
45
45
}
46
46
-
for _, evt := range timeline {
47
47
-
if evt.Repo != nil {
48
48
-
if evt.Repo.Source != "" {
49
49
-
didsToResolve = append(didsToResolve, evt.Source.Did)
46
46
+
for _, byMonth := range timeline.ByMonth {
47
47
+
for _, pe := range byMonth.PullEvents.Items {
48
48
+
didsToResolve = append(didsToResolve, pe.Repo.Did)
49
49
+
}
50
50
+
for _, ie := range byMonth.IssueEvents.Items {
51
51
+
didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did)
52
52
+
}
53
53
+
for _, re := range byMonth.RepoEvents {
54
54
+
didsToResolve = append(didsToResolve, re.Repo.Did)
55
55
+
if re.Source != nil {
56
56
+
didsToResolve = append(didsToResolve, re.Source.Did)
50
57
}
51
58
}
52
52
-
didsToResolve = append(didsToResolve, evt.Repo.Did)
53
59
}
54
60
55
61
resolvedIds := s.resolver.ResolveIdents(r.Context(), didsToResolve)