diff --git a/.gh-dash.yml b/.gh-dash.yml index 349539c6..ad7fe9b9 100644 --- a/.gh-dash.yml +++ b/.gh-dash.yml @@ -80,3 +80,5 @@ theme: primary: "#383B5B" secondary: "#39386B" faint: "#2B2B40" + +showAuthorRole: true diff --git a/README.md b/README.md index 5256f39e..6e185496 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ theme: # optional, see more info below pager: diff: less # or delta for example confirmQuit: false # show prompt on quit or not +showAuthorRole: false # show author role ("new", "member", etc.) ``` ### πŸ—ƒ Running with a different config file diff --git a/config/parser.go b/config/parser.go index 6ec15db8..af79804e 100644 --- a/config/parser.go +++ b/config/parser.go @@ -198,6 +198,7 @@ type Config struct { Theme *ThemeConfig `yaml:"theme,omitempty" validate:"omitempty"` Pager Pager `yaml:"pager"` ConfirmQuit bool `yaml:"confirmQuit"` + ShowAuthorRole bool `yaml:"showAuthorRole"` } type configError struct { @@ -313,6 +314,7 @@ func (parser ConfigParser) getDefaultConfig() Config { }, }, ConfirmQuit: false, + ShowAuthorRole: false, } } diff --git a/data/issueapi.go b/data/issueapi.go index 86a7455e..4300374d 100644 --- a/data/issueapi.go +++ b/data/issueapi.go @@ -17,14 +17,15 @@ type IssueData struct { Author struct { Login string } - UpdatedAt time.Time - CreatedAt time.Time - Url string - Repository Repository - Assignees Assignees `graphql:"assignees(first: 3)"` - Comments IssueComments `graphql:"comments(first: 15)"` - Reactions IssueReactions `graphql:"reactions(first: 1)"` - Labels IssueLabels `graphql:"labels(first: 3)"` + AuthorAssociation string + UpdatedAt time.Time + CreatedAt time.Time + Url string + Repository Repository + Assignees Assignees `graphql:"assignees(first: 3)"` + Comments IssueComments `graphql:"comments(first: 15)"` + Reactions IssueReactions `graphql:"reactions(first: 1)"` + Labels IssueLabels `graphql:"labels(first: 3)"` } type IssueComments struct { @@ -53,6 +54,12 @@ type IssueLabels struct { Nodes []Label } +func (data IssueData) GetAuthor() string { + author := data.Author.Login + author += fmt.Sprintf(" %s", GetAuthorRoleIcon(data.AuthorAssociation)) + return author +} + func (data IssueData) GetTitle() string { return data.Title } diff --git a/data/prapi.go b/data/prapi.go index fbb77102..091ba446 100644 --- a/data/prapi.go +++ b/data/prapi.go @@ -22,16 +22,17 @@ type PullRequestData struct { Author struct { Login string } - UpdatedAt time.Time - CreatedAt time.Time - Url string - State string - Mergeable string - ReviewDecision string - Additions int - Deletions int - HeadRefName string - BaseRefName string + AuthorAssociation string + UpdatedAt time.Time + CreatedAt time.Time + Url string + State string + Mergeable string + ReviewDecision string + Additions int + Deletions int + HeadRefName string + BaseRefName string HeadRepository struct { Name string } @@ -166,6 +167,12 @@ type PageInfo struct { EndCursor string } +func (data PullRequestData) GetAuthor() string { + author := data.Author.Login + author += fmt.Sprintf(" %s", GetAuthorRoleIcon(data.AuthorAssociation)) + return author +} + func (data PullRequestData) GetTitle() string { return data.Title } diff --git a/data/utils.go b/data/utils.go index bad7ff58..e78bb51a 100644 --- a/data/utils.go +++ b/data/utils.go @@ -2,6 +2,9 @@ package data import ( "time" + + "github.com/charmbracelet/lipgloss" + "github.com/dlvhdr/gh-dash/v4/ui/constants" ) type RowData interface { @@ -22,3 +25,21 @@ func IsStatusWaiting(status string) bool { func IsConclusionAFailure(conclusion string) bool { return conclusion == "FAILURE" || conclusion == "TIMED_OUT" || conclusion == "STARTUP_FAILURE" } + +func GetAuthorRoleIcon(role string) string { + // https://docs.github.com/en/graphql/reference/enums#commentauthorassociation + switch role { + case "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "NONE": + return lipgloss.NewStyle().Foreground(lipgloss.Color(constants.NewContributorColor)).Render(constants.NewContributorIcon) + case "COLLABORATOR": + return lipgloss.NewStyle().Foreground(lipgloss.Color(constants.CollaboratorColor)).Render(constants.CollaboratorIcon) + case "CONTRIBUTOR": + return lipgloss.NewStyle().Foreground(lipgloss.Color(constants.ContributorColor)).Render(constants.ContributorIcon) + case "MEMBER": + return lipgloss.NewStyle().Foreground(lipgloss.Color(constants.MemberColor)).Render(constants.MemberIcon) + case "OWNER": + return lipgloss.NewStyle().Foreground(lipgloss.Color(constants.OwnerColor)).Render(constants.OwnerIcon) + default: + return constants.UnknownRoleIcon + } +} diff --git a/ui/components/issue/issue.go b/ui/components/issue/issue.go index 1a696b92..1b9fb4f2 100644 --- a/ui/components/issue/issue.go +++ b/ui/components/issue/issue.go @@ -72,7 +72,7 @@ func (issue *Issue) renderTitle() string { } func (issue *Issue) renderOpenedBy() string { - return issue.getTextStyle().Render(issue.Data.Author.Login) + return issue.getTextStyle().Render(issue.Data.GetAuthor()) } func (issue *Issue) renderAssignees() string { diff --git a/ui/components/pr/pr.go b/ui/components/pr/pr.go index e001b155..03c84118 100644 --- a/ui/components/pr/pr.go +++ b/ui/components/pr/pr.go @@ -191,7 +191,7 @@ func (pr *PullRequest) renderExtendedTitle(isSelected bool) string { baseStyle = baseStyle.Foreground(pr.Ctx.Theme.SecondaryText).Background(pr.Ctx.Theme.SelectedBackground) } - author := baseStyle.Render(fmt.Sprintf("@%s", pr.Data.Author.Login)) + author := baseStyle.Render(fmt.Sprintf("@%s", pr.Data.GetAuthor())) top := lipgloss.JoinHorizontal(lipgloss.Top, pr.Data.Repository.NameWithOwner, fmt.Sprintf(" #%d by %s", pr.Data.Number, author)) branchHidden := pr.Ctx.Config.Defaults.Layout.Prs.Base.Hidden if branchHidden == nil || !*branchHidden { @@ -213,7 +213,7 @@ func (pr *PullRequest) renderExtendedTitle(isSelected bool) string { } func (pr *PullRequest) renderAuthor() string { - return pr.getTextStyle().Render(pr.Data.Author.Login) + return pr.getTextStyle().Render(pr.Data.GetAuthor()) } func (pr *PullRequest) renderAssignees() string { diff --git a/ui/constants/constants.go b/ui/constants/constants.go index 5de457e4..0ffb845c 100644 --- a/ui/constants/constants.go +++ b/ui/constants/constants.go @@ -36,4 +36,25 @@ const ( MergedIcon = "" OpenIcon = "" ClosedIcon = "ο“œ" + + NewContributorIcon = "󱃱" // U+F10F1 nf-md-hand_heart + ContributorIcon = "󱕾" // U+F157E nf-md-hand_heart_outline + CollaboratorIcon = "ξΆ " // U+EDA0 nf-fa-handshake_simple + MemberIcon = "" // U+ED9F nf-fa-handshake_angle + OwnerIcon = "" // U+ED9F nf-fa-handshake_angle + UnknownRoleIcon = "󱐑" // U+F1421 nf-md-incognito_circle + + // NewContributorIcon = "󰲑" // U+F0CA1 nf-md-numeric_1_circle_outline + // ContributorIcon = "󰦀" // U+F09A4 nf-md-star_circle_outline + // CollaboratorIcon = "󱟝" // U+F17DD nf-md-crown_circle_outline + // MemberIcon = "󱟝" // U+F17DD nf-md-crown_circle_outline + // OwnerIcon = "󱟜" // U+F17DC nf-md-crown_circle + // UnknownRoleIcon = "󱐑" // U+F1421 nf-md-incognito_circle + + NewContributorColor = "77" // PaleGreen3 + ContributorColor = "75" // SteelBlue1 + CollaboratorColor = "178" // Gold3 + MemberColor = "178" // Gold3 + OwnerColor = "178" // Gold3 + )