X Tutup
Skip to content

Commit c843a4f

Browse files
committed
Add issue comment viewing
1 parent f415245 commit c843a4f

16 files changed

+1407
-88
lines changed

api/queries_issue.go

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,8 @@ type Issue struct {
3333
Body string
3434
CreatedAt time.Time
3535
UpdatedAt time.Time
36-
Comments struct {
37-
TotalCount int
38-
}
39-
Author struct {
40-
Login string
41-
}
36+
Comments IssueComments
37+
Author Author
4238
Assignees struct {
4339
Nodes []struct {
4440
Login string
@@ -65,12 +61,31 @@ type Issue struct {
6561
Milestone struct {
6662
Title string
6763
}
64+
ReactionGroups ReactionGroups
6865
}
6966

7067
type IssuesDisabledError struct {
7168
error
7269
}
7370

71+
type IssueComments struct {
72+
Nodes []IssueComment
73+
TotalCount int
74+
}
75+
76+
type IssueComment struct {
77+
Author Author
78+
AuthorAssociation string
79+
Body string
80+
CreatedAt time.Time
81+
IncludesCreatedEdit bool
82+
ReactionGroups ReactionGroups
83+
}
84+
85+
type Author struct {
86+
Login string
87+
}
88+
7489
const fragments = `
7590
fragment issue on Issue {
7691
number
@@ -320,7 +335,7 @@ loop:
320335
return &res, nil
321336
}
322337

323-
func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, error) {
338+
func IssueByNumber(client *Client, repo ghrepo.Interface, number, comments int) (*Issue, error) {
324339
type response struct {
325340
Repository struct {
326341
Issue Issue
@@ -329,7 +344,7 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, e
329344
}
330345

331346
query := `
332-
query IssueByNumber($owner: String!, $repo: String!, $issue_number: Int!) {
347+
query IssueByNumber($owner: String!, $repo: String!, $issue_number: Int!, $comments: Int!) {
333348
repository(owner: $owner, name: $repo) {
334349
hasIssuesEnabled
335350
issue(number: $issue_number) {
@@ -341,7 +356,22 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, e
341356
author {
342357
login
343358
}
344-
comments {
359+
comments(last: $comments) {
360+
nodes {
361+
author {
362+
login
363+
}
364+
authorAssociation
365+
body
366+
createdAt
367+
includesCreatedEdit
368+
reactionGroups {
369+
content
370+
users {
371+
totalCount
372+
}
373+
}
374+
}
345375
totalCount
346376
}
347377
number
@@ -370,9 +400,15 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, e
370400
}
371401
totalCount
372402
}
373-
milestone{
403+
milestone {
374404
title
375405
}
406+
reactionGroups {
407+
content
408+
users {
409+
totalCount
410+
}
411+
}
376412
}
377413
}
378414
}`
@@ -381,6 +417,7 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, e
381417
"owner": repo.RepoOwner(),
382418
"repo": repo.RepoName(),
383419
"issue_number": number,
420+
"comments": comments,
384421
}
385422

386423
var resp response

api/reaction_groups.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package api
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type ReactionGroups []ReactionGroup
9+
10+
type ReactionGroup struct {
11+
Content string
12+
Users ReactionGroupUsers
13+
}
14+
15+
type ReactionGroupUsers struct {
16+
TotalCount int
17+
}
18+
19+
func (rg ReactionGroup) String() string {
20+
c := rg.Users.TotalCount
21+
if c == 0 {
22+
return ""
23+
}
24+
e := reactionEmoji[rg.Content]
25+
if e == "" {
26+
return ""
27+
}
28+
return fmt.Sprintf("%v %s", c, e)
29+
}
30+
31+
func (rgs ReactionGroups) String() string {
32+
var rs []string
33+
34+
for _, rg := range rgs {
35+
if r := rg.String(); r != "" {
36+
rs = append(rs, r)
37+
}
38+
}
39+
40+
return strings.Join(rs, " • ")
41+
}
42+
43+
var reactionEmoji = map[string]string{
44+
"THUMBS_UP": "\U0001f44d",
45+
"THUMBS_DOWN": "\U0001f44e",
46+
"LAUGH": "\U0001f604",
47+
"HOORAY": "\U0001f389",
48+
"CONFUSED": "\U0001f615",
49+
"HEART": "\u2764\ufe0f",
50+
"ROCKET": "\U0001f680",
51+
"EYES": "\U0001f440",
52+
}

api/reaction_groups_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package api
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_String(t *testing.T) {
10+
tests := map[string]struct {
11+
rgs ReactionGroups
12+
output string
13+
}{
14+
"empty reaction groups": {
15+
rgs: []ReactionGroup{},
16+
output: `^$`,
17+
},
18+
"non-empty reaction groups": {
19+
rgs: []ReactionGroup{
20+
ReactionGroup{
21+
Content: "LAUGH",
22+
Users: ReactionGroupUsers{TotalCount: 0},
23+
},
24+
ReactionGroup{
25+
Content: "HOORAY",
26+
Users: ReactionGroupUsers{TotalCount: 1},
27+
},
28+
ReactionGroup{
29+
Content: "CONFUSED",
30+
Users: ReactionGroupUsers{TotalCount: 0},
31+
},
32+
ReactionGroup{
33+
Content: "HEART",
34+
Users: ReactionGroupUsers{TotalCount: 2},
35+
},
36+
},
37+
output: `^1 \x{1f389} • 2 \x{2764}\x{fe0f}$`,
38+
},
39+
"reaction groups with unmapped emoji": {
40+
rgs: []ReactionGroup{
41+
ReactionGroup{
42+
Content: "UNKNOWN",
43+
Users: ReactionGroupUsers{TotalCount: 1},
44+
},
45+
},
46+
output: `^$`,
47+
},
48+
}
49+
50+
for name, tt := range tests {
51+
t.Run(name, func(t *testing.T) {
52+
assert.Regexp(t, tt.output, tt.rgs.String())
53+
})
54+
}
55+
}

pkg/cmd/issue/shared/lookup.go

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,55 @@ import (
1111
"github.com/cli/cli/internal/ghrepo"
1212
)
1313

14-
func IssueFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string) (*api.Issue, ghrepo.Interface, error) {
15-
issue, baseRepo, err := issueFromURL(apiClient, arg)
16-
if err != nil {
17-
return nil, nil, err
18-
}
19-
if issue != nil {
20-
return issue, baseRepo, nil
21-
}
14+
func IssueWithCommentsFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string, comments int) (*api.Issue, ghrepo.Interface, error) {
15+
issueNumber, baseRepo := issueMetadataFromURL(arg)
2216

23-
baseRepo, err = baseRepoFn()
24-
if err != nil {
25-
return nil, nil, fmt.Errorf("could not determine base repo: %w", err)
17+
if baseRepo == nil {
18+
var err error
19+
baseRepo, err = baseRepoFn()
20+
if err != nil {
21+
return nil, nil, fmt.Errorf("could not determine base repo: %w", err)
22+
}
2623
}
2724

28-
issueNumber, err := strconv.Atoi(strings.TrimPrefix(arg, "#"))
29-
if err != nil {
30-
return nil, nil, fmt.Errorf("invalid issue format: %q", arg)
25+
if issueNumber == 0 {
26+
var err error
27+
issueNumber, err = strconv.Atoi(strings.TrimPrefix(arg, "#"))
28+
if err != nil {
29+
return nil, nil, fmt.Errorf("invalid issue format: %q", arg)
30+
}
3131
}
3232

33-
issue, err = issueFromNumber(apiClient, baseRepo, issueNumber)
33+
issue, err := issueFromNumber(apiClient, baseRepo, issueNumber, comments)
3434
return issue, baseRepo, err
3535
}
3636

37+
func IssueFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string) (*api.Issue, ghrepo.Interface, error) {
38+
return IssueWithCommentsFromArg(apiClient, baseRepoFn, arg, 0)
39+
}
40+
3741
var issueURLRE = regexp.MustCompile(`^/([^/]+)/([^/]+)/issues/(\d+)`)
3842

39-
func issueFromURL(apiClient *api.Client, s string) (*api.Issue, ghrepo.Interface, error) {
43+
func issueMetadataFromURL(s string) (int, ghrepo.Interface) {
4044
u, err := url.Parse(s)
4145
if err != nil {
42-
return nil, nil, nil
46+
return 0, nil
4347
}
4448

4549
if u.Scheme != "https" && u.Scheme != "http" {
46-
return nil, nil, nil
50+
return 0, nil
4751
}
4852

4953
m := issueURLRE.FindStringSubmatch(u.Path)
5054
if m == nil {
51-
return nil, nil, nil
55+
return 0, nil
5256
}
5357

5458
repo := ghrepo.NewWithHost(m[1], m[2], u.Hostname())
5559
issueNumber, _ := strconv.Atoi(m[3])
56-
issue, err := issueFromNumber(apiClient, repo, issueNumber)
57-
return issue, repo, err
60+
return issueNumber, repo
5861
}
5962

60-
func issueFromNumber(apiClient *api.Client, repo ghrepo.Interface, issueNumber int) (*api.Issue, error) {
61-
return api.IssueByNumber(apiClient, repo, issueNumber)
63+
func issueFromNumber(apiClient *api.Client, repo ghrepo.Interface, issueNumber, comments int) (*api.Issue, error) {
64+
return api.IssueByNumber(apiClient, repo, issueNumber, comments)
6265
}

pkg/cmd/issue/view/fixtures/issueView_preview.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@
77
"body": "**bold story**",
88
"title": "ix of coins",
99
"state": "OPEN",
10-
"created_at": "2011-01-26T19:01:12Z",
10+
"createdAt": "2011-01-26T19:01:12Z",
1111
"author": {
1212
"login": "marseilles"
1313
},
1414
"assignees": {
1515
"nodes": [],
16-
"totalcount": 0
16+
"totalCount": 0
1717
},
1818
"labels": {
1919
"nodes": [],
20-
"totalcount": 0
20+
"totalCount": 0
2121
},
2222
"projectcards": {
2323
"nodes": [],
24-
"totalcount": 0
24+
"totalCount": 0
2525
},
2626
"milestone": {
2727
"title": ""

pkg/cmd/issue/view/fixtures/issueView_previewClosedState.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"body": "**bold story**",
88
"title": "ix of coins",
99
"state": "CLOSED",
10-
"created_at": "2011-01-26T19:01:12Z",
10+
"createdAt": "2011-01-26T19:01:12Z",
1111
"author": {
1212
"login": "marseilles"
1313
},

0 commit comments

Comments
 (0)
X Tutup