Skip to content

Commit

Permalink
feat(prs): show review threads in sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
dlvhdr committed Feb 17, 2024
1 parent b5d8e2f commit bf3764c
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 21 deletions.
15 changes: 14 additions & 1 deletion data/issueapi.go
Expand Up @@ -21,11 +21,24 @@ type IssueData struct {
Url string

This comment has been minimized.

Copy link
@JADJO
Repository Repository
Assignees Assignees `graphql:"assignees(first: 3)"`
Comments Comments `graphql:"comments(first: 15)"`
Comments IssueComments `graphql:"comments(first: 15)"`
Reactions IssueReactions `graphql:"reactions(first: 1)"`
Labels IssueLabels `graphql:"labels(first: 3)"`
}

type IssueComments struct {
Nodes []IssueComment
TotalCount int
}

type IssueComment struct {
Author struct {
Login string
}
Body string
UpdatedAt time.Time
}

type IssueReactions struct {
TotalCount int
}
Expand Down
34 changes: 31 additions & 3 deletions data/prapi.go
Expand Up @@ -34,9 +34,10 @@ type PullRequestData struct {
Name string
}
Repository Repository
Assignees Assignees `graphql:"assignees(first: 3)"`
Comments Comments `graphql:"comments(last: 5, orderBy: { field: UPDATED_AT, direction: DESC })"`
LatestReviews Reviews `graphql:"latestReviews(last: 3)"`
Assignees Assignees `graphql:"assignees(first: 3)"`
Comments Comments `graphql:"comments(last: 5, orderBy: { field: UPDATED_AT, direction: DESC })"`
LatestReviews Reviews `graphql:"latestReviews(last: 3)"`
ReviewThreads ReviewThreads `graphql:"reviewThreads(last: 100)"`
IsDraft bool
Commits Commits `graphql:"commits(last: 1)"`
}
Expand Down Expand Up @@ -96,6 +97,21 @@ type Comment struct {
UpdatedAt time.Time
}

type ReviewComment struct {
Author struct {
Login string
}
Body string
UpdatedAt time.Time
StartLine int
Line int
}

type ReviewComments struct {
Nodes []ReviewComment
TotalCount int
}

type Comments struct {
Nodes []Comment
TotalCount int
Expand All @@ -114,6 +130,18 @@ type Reviews struct {
Nodes []Review
}

type ReviewThreads struct {
Nodes []struct {
Id string
IsOutdated bool
OriginalLine int
StartLine int
Line int
Path string
Comments ReviewComments `graphql:"comments(first: 100)"`
}
}

type PageInfo struct {
HasNextPage bool
StartCursor string
Expand Down
3 changes: 2 additions & 1 deletion ui/components/issuesidebar/activity.go
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/charmbracelet/glamour"
"github.com/charmbracelet/lipgloss"

"github.com/dlvhdr/gh-dash/data"
"github.com/dlvhdr/gh-dash/ui/markdown"
"github.com/dlvhdr/gh-dash/utils"
Expand Down Expand Up @@ -63,7 +64,7 @@ func renderEmptyState() string {
return lipgloss.NewStyle().Italic(true).Render("No comments...")
}

func (m *Model) renderComment(comment data.Comment, markdownRenderer glamour.TermRenderer) (string, error) {
func (m *Model) renderComment(comment data.IssueComment, markdownRenderer glamour.TermRenderer) (string, error) {
header := lipgloss.JoinHorizontal(lipgloss.Top,
m.ctx.Styles.Common.MainTextStyle.Copy().Render(comment.Author.Login),
" ",
Expand Down
3 changes: 2 additions & 1 deletion ui/components/issuesidebar/comment.go
Expand Up @@ -6,6 +6,7 @@ import (
"time"

tea "github.com/charmbracelet/bubbletea"

"github.com/dlvhdr/gh-dash/data"
"github.com/dlvhdr/gh-dash/ui/components/issuessection"
"github.com/dlvhdr/gh-dash/ui/constants"
Expand Down Expand Up @@ -44,7 +45,7 @@ func (m *Model) comment(body string) tea.Cmd {
Err: err,
Msg: issuessection.UpdateIssueMsg{
IssueNumber: issueNumber,
NewComment: &data.Comment{
NewComment: &data.IssueComment{
Author: struct{ Login string }{Login: m.ctx.User},
Body: body,
UpdatedAt: time.Now(),
Expand Down
2 changes: 1 addition & 1 deletion ui/components/issuessection/issuessection.go
Expand Up @@ -344,7 +344,7 @@ type SectionIssuesFetchedMsg struct {

type UpdateIssueMsg struct {
IssueNumber int
NewComment *data.Comment
NewComment *data.IssueComment
IsClosed *bool
AddedAssignees *data.Assignees
RemovedAssignees *data.Assignees
Expand Down
81 changes: 67 additions & 14 deletions ui/components/prsidebar/activity.go
@@ -1,12 +1,14 @@
package prsidebar

import (
"fmt"
"regexp"
"sort"
"time"

"github.com/charmbracelet/glamour"
"github.com/charmbracelet/lipgloss"

"github.com/dlvhdr/gh-dash/data"
"github.com/dlvhdr/gh-dash/ui/markdown"
"github.com/dlvhdr/gh-dash/utils"
Expand All @@ -21,13 +23,37 @@ func (m *Model) renderActivity() string {
width := m.getIndentedContentWidth() - 2
markdownRenderer := markdown.GetMarkdownRenderer(width)

var activity []RenderedActivity
for _, comment := range m.pr.Data.Comments.Nodes {
var activities []RenderedActivity
var comments []comment

for _, review := range m.pr.Data.ReviewThreads.Nodes {
path := review.Path
line := review.Line
for _, c := range review.Comments.Nodes {
comments = append(comments, comment{
Author: c.Author.Login,
Body: c.Body,
UpdatedAt: c.UpdatedAt,
Path: &path,
Line: &line,
})
}
}

for _, c := range m.pr.Data.Comments.Nodes {
comments = append(comments, comment{
Author: c.Author.Login,
Body: c.Body,
UpdatedAt: c.UpdatedAt,
})
}

for _, comment := range comments {
renderedComment, err := m.renderComment(comment, markdownRenderer)
if err != nil {
continue
}
activity = append(activity, RenderedActivity{
activities = append(activities, RenderedActivity{
UpdatedAt: comment.UpdatedAt,
RenderedString: renderedComment,
})
Expand All @@ -38,23 +64,23 @@ func (m *Model) renderActivity() string {
if err != nil {
continue
}
activity = append(activity, RenderedActivity{
activities = append(activities, RenderedActivity{
UpdatedAt: review.UpdatedAt,
RenderedString: renderedReview,
})
}

sort.Slice(activity, func(i, j int) bool {
return activity[i].UpdatedAt.Before(activity[j].UpdatedAt)
sort.Slice(activities, func(i, j int) bool {
return activities[i].UpdatedAt.Before(activities[j].UpdatedAt)
})

body := ""
bodyStyle := lipgloss.NewStyle().PaddingLeft(2)
if len(activity) == 0 {
if len(activities) == 0 {
body = renderEmptyState()
} else {
var renderedActivities []string
for _, activity := range activity {
for _, activity := range activities {
renderedActivities = append(renderedActivities, activity.RenderedString)
}
body = lipgloss.JoinVertical(lipgloss.Left, renderedActivities...)
Expand All @@ -74,12 +100,39 @@ func renderEmptyState() string {
return lipgloss.NewStyle().Italic(true).Render("No comments...")
}

func (m *Model) renderComment(comment data.Comment, markdownRenderer glamour.TermRenderer) (string, error) {
header := lipgloss.JoinHorizontal(lipgloss.Top,
m.ctx.Styles.Common.MainTextStyle.Copy().Render(comment.Author.Login),
" ",
lipgloss.NewStyle().Foreground(m.ctx.Theme.FaintText).Render(utils.TimeElapsed(comment.UpdatedAt)),
)
type comment struct {
Author string
UpdatedAt time.Time
Body string
Path *string
Line *int
}

func (m *Model) renderComment(comment comment, markdownRenderer glamour.TermRenderer) (string, error) {
width := m.getIndentedContentWidth()
authorAndTime := lipgloss.NewStyle().
Width(width).
BorderStyle(lipgloss.RoundedBorder()).
BorderForeground(m.ctx.Theme.FaintBorder).Render(
lipgloss.JoinHorizontal(lipgloss.Top,
m.ctx.Styles.Common.MainTextStyle.Copy().Render(comment.Author),
" ",
lipgloss.NewStyle().Foreground(m.ctx.Theme.FaintText).Render(utils.TimeElapsed(comment.UpdatedAt)),
))

var header string
if comment.Path != nil && comment.Line != nil {
filePath := lipgloss.NewStyle().Foreground(m.ctx.Theme.FaintText).Width(width).Render(
fmt.Sprintf(
"%s#l%d",
*comment.Path,
*comment.Line,
),
)
header = lipgloss.JoinVertical(lipgloss.Left, authorAndTime, filePath, "")
} else {
header = authorAndTime
}

regex := regexp.MustCompile(`((\n)+|^)([^\r\n]*\|[^\r\n]*(\n)?)+`)
body := regex.ReplaceAllString(comment.Body, "")
Expand Down
1 change: 1 addition & 0 deletions ui/ui.go
Expand Up @@ -361,6 +361,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if ok {
log.Debug("Task finished", "id", task.Id)
if msg.Err != nil {
log.Error("Task finished with error", "id", task.Id, "err", msg.Err)
task.State = context.TaskError
task.Error = msg.Err
} else {
Expand Down

0 comments on commit bf3764c

Please sign in to comment.