Skip to content

Commit c8195ef

Browse files
committed
feat(metrics): add reaction metric pill
Signed-off-by: Adam Setch <adam.setch@outlook.com>
1 parent bcfd0b9 commit c8195ef

File tree

15 files changed

+2670
-57
lines changed

15 files changed

+2670
-57
lines changed

src/renderer/components/metrics/MetricGroup.test.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,66 @@ describe('renderer/components/metrics/MetricGroup.tsx', () => {
4848
});
4949
});
5050

51+
describe('reactions pills', () => {
52+
it('should render reaction pill when one reaction', async () => {
53+
const mockNotification = mockGitifyNotification;
54+
mockNotification.subject.reactionsCount = 1;
55+
mockNotification.subject.reactionGroups = [
56+
{
57+
content: 'ROCKET',
58+
reactors: {
59+
totalCount: 1,
60+
},
61+
},
62+
];
63+
64+
const props: MetricGroupProps = {
65+
notification: mockNotification,
66+
};
67+
68+
const tree = renderWithAppContext(<MetricGroup {...props} />);
69+
expect(tree).toMatchSnapshot();
70+
});
71+
72+
it('should render reaction pill when multiple reactions', async () => {
73+
const mockNotification = mockGitifyNotification;
74+
mockNotification.subject.reactionsCount = 2;
75+
mockNotification.subject.reactionGroups = [
76+
{
77+
content: 'THUMBS_UP',
78+
reactors: {
79+
totalCount: 1,
80+
},
81+
},
82+
{
83+
content: 'ROCKET',
84+
reactors: {
85+
totalCount: 1,
86+
},
87+
},
88+
];
89+
90+
const props: MetricGroupProps = {
91+
notification: mockNotification,
92+
};
93+
94+
const tree = renderWithAppContext(<MetricGroup {...props} />);
95+
expect(tree).toMatchSnapshot();
96+
});
97+
98+
it('should render issues pill when linked to multiple issues/prs', async () => {
99+
const mockNotification = mockGitifyNotification;
100+
mockNotification.subject.linkedIssues = ['#1', '#2'];
101+
102+
const props: MetricGroupProps = {
103+
notification: mockNotification,
104+
};
105+
106+
const tree = renderWithAppContext(<MetricGroup {...props} />);
107+
expect(tree).toMatchSnapshot();
108+
});
109+
});
110+
51111
describe('comment pills', () => {
52112
it('should render when no comments', async () => {
53113
const mockNotification = mockGitifyNotification;

src/renderer/components/metrics/MetricGroup.tsx

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
CommentIcon,
55
IssueOpenedIcon,
66
MilestoneIcon,
7+
SmileyIcon,
78
TagIcon,
89
} from '@primer/octicons-react';
910

@@ -27,22 +28,72 @@ export const MetricGroup: FC<MetricGroupProps> = ({
2728
const hasLinkedIssues = linkedIssues.length > 0;
2829
const linkedIssuesPillDescription = hasLinkedIssues
2930
? `Linked to ${
30-
linkedIssues.length > 1 ? 'issues' : 'issue'
31+
linkedIssues.length > 1 ? 'issues:' : 'issue'
3132
} ${linkedIssues.join(', ')}`
3233
: '';
3334

35+
const reactionCount = notification.subject.reactionsCount ?? 0;
36+
const reactionGroups = notification.subject.reactionGroups ?? [];
37+
const hasReactions = reactionCount > 0;
38+
const hasMultipleReactions =
39+
reactionGroups.filter((rg) => rg.reactors.totalCount > 0).length > 1;
40+
const reactionPillDescription = hasReactions
41+
? `${reactionCount} ${
42+
reactionCount > 1 ? 'reactions' : 'reaction'
43+
}: ${reactionGroups
44+
.reduce((acc, rg) => {
45+
if (!rg.reactors.totalCount || rg.reactors.totalCount <= 0) {
46+
return acc;
47+
}
48+
49+
let emoji = '';
50+
switch (rg.content) {
51+
case 'THUMBS_UP':
52+
emoji = '👍';
53+
break;
54+
case 'THUMBS_DOWN':
55+
emoji = '👎';
56+
break;
57+
case 'LAUGH':
58+
emoji = '😆';
59+
break;
60+
case 'HOORAY':
61+
emoji = '🎉';
62+
break;
63+
case 'CONFUSED':
64+
emoji = '😕';
65+
break;
66+
case 'ROCKET':
67+
emoji = '🚀';
68+
break;
69+
case 'EYES':
70+
emoji = '👀';
71+
break;
72+
case 'HEART':
73+
emoji = '❤️';
74+
break;
75+
default:
76+
return acc;
77+
}
78+
acc.push(
79+
`${emoji} ${hasMultipleReactions ? rg.reactors.totalCount : ''}`.trim(),
80+
);
81+
return acc;
82+
}, [] as string[])
83+
.join(' ')}`
84+
: '';
85+
3486
const commentCount = notification.subject.commentCount ?? 0;
3587
const hasComments = commentCount > 0;
3688
const commentsPillDescription = hasComments
37-
? `${notification.subject.commentCount} ${
38-
notification.subject.commentCount > 1 ? 'comments' : 'comment'
39-
}`
89+
? `${notification.subject.commentCount} ${notification.subject.commentCount > 1 ? 'comments' : 'comment'}`
4090
: '';
4191

4292
const labels = notification.subject.labels ?? [];
43-
const hasLabels = labels.length > 0;
93+
const labelsCount = labels.length;
94+
const hasLabels = labelsCount > 0;
4495
const labelsPillDescription = hasLabels
45-
? labels.map((label) => `🏷️ ${label}`).join(', ')
96+
? `${labelsCount} ${labelsCount > 1 ? 'labels' : 'label'}: ${labels.map((label) => `🏷️ ${label}`).join(', ')}`
4697
: '';
4798

4899
const milestone = notification.subject.milestone;
@@ -59,6 +110,15 @@ export const MetricGroup: FC<MetricGroupProps> = ({
59110
/>
60111
)}
61112

113+
{hasReactions && (
114+
<MetricPill
115+
color={IconColor.GRAY}
116+
icon={SmileyIcon}
117+
metric={notification.subject.reactionsCount}
118+
title={reactionPillDescription}
119+
/>
120+
)}
121+
62122
{notification.subject.reviews?.map((review) => {
63123
const icon = getPullRequestReviewIcon(review);
64124
if (!icon) {

0 commit comments

Comments
 (0)