Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/renderer/utils/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ export async function fetchIssueByNumber(
notification.account.token,
FetchIssueByNumberDocument,
{
owner: notification.repository.owner.login,
name: notification.repository.name,
number: number,
ownerINDEX: notification.repository.owner.login,
nameINDEX: notification.repository.name,
numberINDEX: number,
firstLabels: 100,
lastComments: 1,
},
Expand All @@ -230,11 +230,11 @@ export async function fetchPullByNumber(
notification.account.token,
FetchPullRequestByNumberDocument,
{
owner: notification.repository.owner.login,
name: notification.repository.name,
number: number,
firstLabels: 100,
ownerINDEX: notification.repository.owner.login,
nameINDEX: notification.repository.name,
numberINDEX: number,
firstClosingIssues: 100,
firstLabels: 100,
lastComments: 1,
lastReviews: 100,
},
Expand All @@ -255,12 +255,12 @@ export async function fetchDiscussionByNumber(
notification.account.token,
FetchDiscussionByNumberDocument,
{
owner: notification.repository.owner.login,
name: notification.repository.name,
number: number,
ownerINDEX: notification.repository.owner.login,
nameINDEX: notification.repository.name,
numberINDEX: number,
firstLabels: 100,
lastComments: 10,
lastReplies: 10,
firstLabels: 100,
includeIsAnswered: isAnsweredDiscussionFeatureSupported(
notification.account,
),
Expand Down
14 changes: 9 additions & 5 deletions src/renderer/utils/api/graphql/discussion.graphql
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
query FetchDiscussionByNumber(
$owner: String!
$name: String!
$number: Int!
$ownerINDEX: String!
$nameINDEX: String!
$numberINDEX: Int!
$lastComments: Int
$lastReplies: Int
$firstLabels: Int
$includeIsAnswered: Boolean!
) {
repository(owner: $owner, name: $name) {
discussion(number: $number) {
...DiscussionMergeQuery
}

fragment DiscussionMergeQuery on Query {
nodeINDEX: repository(owner: $ownerINDEX, name: $nameINDEX) {
discussion(number: $numberINDEX) {
...DiscussionDetails
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/renderer/utils/api/graphql/generated/gql.ts

Large diffs are not rendered by default.

285 changes: 256 additions & 29 deletions src/renderer/utils/api/graphql/generated/graphql.ts

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/renderer/utils/api/graphql/issue.graphql
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
query FetchIssueByNumber(
$owner: String!
$name: String!
$number: Int!
$ownerINDEX: String!
$nameINDEX: String!
$numberINDEX: Int!
$lastComments: Int
$firstLabels: Int
) {
repository(owner: $owner, name: $name) {
issue(number: $number) {
...IssueMergeQuery
}
fragment IssueMergeQuery on Query {
nodeINDEX: repository(owner: $ownerINDEX, name: $nameINDEX) {
issue(number: $numberINDEX) {
...IssueDetails
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/renderer/utils/api/graphql/pull.graphql
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
query FetchPullRequestByNumber(
$owner: String!
$name: String!
$number: Int!
$ownerINDEX: String!
$nameINDEX: String!
$numberINDEX: Int!
$firstLabels: Int
$lastComments: Int
$lastReviews: Int
$firstClosingIssues: Int
) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
...PullRequestMergeQuery
}

fragment PullRequestMergeQuery on Query {
nodeINDEX: repository(owner: $ownerINDEX, name: $nameINDEX) {
pullRequest(number: $numberINDEX) {
...PullRequestDetails
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/renderer/utils/api/graphql/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export function getQueryFragmentBody(doc: string): string | null {
// Find fragment on Query pattern
const fragmentMatch = doc.match(/fragment\s+\w+\s+on\s+Query\s+\{/);
if (!fragmentMatch) {
return null;
}

const start = fragmentMatch.index + fragmentMatch[0].length - 1; // Position of opening brace
let depth = 0;

for (let i = start; i < doc.length; i++) {
if (doc[i] === '{') {
depth++;
} else if (doc[i] === '}') {
depth--;
if (depth === 0) {
return doc.slice(start + 1, i).trim();
}
}
}
return null;
}
1 change: 1 addition & 0 deletions src/renderer/utils/notifications/handlers/checkSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class CheckSuiteHandler extends DefaultHandler {
async enrich(
notification: Notification,
_settings: SettingsState,
_fetchedData?: unknown,
): Promise<GitifySubject> {
const state = getCheckSuiteAttributes(notification)?.status;

Expand Down
3 changes: 2 additions & 1 deletion src/renderer/utils/notifications/handlers/commit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import { getNotificationAuthor } from './utils';
class CommitHandler extends DefaultHandler {
readonly type = 'Commit';

async enrich(
async fetchAndEnrich(
notification: Notification,
settings: SettingsState,
_fetchedData?: unknown,
): Promise<GitifySubject> {
const commitState: GitifyNotificationState = null; // Commit notifications are stateless

Expand Down
16 changes: 16 additions & 0 deletions src/renderer/utils/notifications/handlers/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,25 @@ import { formatForDisplay } from './utils';
export class DefaultHandler implements NotificationTypeHandler {
type?: SubjectType;

mergeQueryConfig() {
return undefined;
}

query(_notification: Notification) {
return null;
}

async fetchAndEnrich(
_notification: Notification,
_settings: SettingsState,
): Promise<GitifySubject> {
return null;
}

async enrich(
_notification: Notification,
_settings: SettingsState,
_fetchedData?: unknown,
): Promise<GitifySubject> {
return null;
}
Expand Down
39 changes: 34 additions & 5 deletions src/renderer/utils/notifications/handlers/discussion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,51 @@ import {
} from '../../../types';
import type { Notification, Subject } from '../../../typesGitHub';
import { fetchDiscussionByNumber } from '../../api/client';
import type {
CommentFieldsFragment,
DiscussionCommentFieldsFragment,
import {
type CommentFieldsFragment,
type DiscussionCommentFieldsFragment,
type DiscussionDetailsFragment,
DiscussionDetailsFragmentDoc,
DiscussionMergeQueryFragmentDoc,
} from '../../api/graphql/generated/graphql';
import { getQueryFragmentBody } from '../../api/graphql/utils';
import { DefaultHandler, defaultHandler } from './default';
import type { GraphQLMergedQueryConfig } from './types';
import { getNotificationAuthor } from './utils';

class DiscussionHandler extends DefaultHandler {
readonly type = 'Discussion';

mergeQueryConfig() {
return {
queryFragment: getQueryFragmentBody(
DiscussionMergeQueryFragmentDoc.toString(),
),
responseFragment: DiscussionDetailsFragmentDoc.toString(),
extras: [
{ name: 'lastComments', type: 'Int', defaultValue: 100 },
{ name: 'lastReplies', type: 'Int', defaultValue: 100 },
{ name: 'firstLabels', type: 'Int', defaultValue: 100 },
{ name: 'includeIsAnswered', type: 'Boolean!', defaultValue: true },
],
selection: (
index: number,
) => `node${index}: repository(owner: $owner${index}, name: $name${index}) {
discussion(number: $number${index}) {
...DiscussionDetails
}
}`,
} as GraphQLMergedQueryConfig;
}

async enrich(
notification: Notification,
_settings: SettingsState,
fetchedData?: DiscussionDetailsFragment,
): Promise<GitifySubject> {
const response = await fetchDiscussionByNumber(notification);
const discussion = response.data.repository?.discussion;
const discussion =
fetchedData ??
(await fetchDiscussionByNumber(notification)).data.nodeINDEX?.discussion;

let discussionState: GitifyDiscussionState = 'OPEN';

Expand Down
35 changes: 31 additions & 4 deletions src/renderer/utils/notifications/handlers/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,46 @@ import type {
} from '../../../types';
import { IconColor } from '../../../types';
import type { Notification, Subject } from '../../../typesGitHub';
import { fetchIssueByNumber } from '../../api/client';
import {
type IssueDetailsFragment,
IssueDetailsFragmentDoc,
IssueMergeQueryFragmentDoc,
} from '../../api/graphql/generated/graphql';
import { getQueryFragmentBody } from '../../api/graphql/utils';
import { DefaultHandler, defaultHandler } from './default';
import type { GraphQLMergedQueryConfig } from './types';
import { getNotificationAuthor } from './utils';

class IssueHandler extends DefaultHandler {
readonly type = 'Issue';

mergeQueryConfig() {
return {
queryFragment: getQueryFragmentBody(
IssueMergeQueryFragmentDoc.toString(),
),

responseFragment: IssueDetailsFragmentDoc.toString(),
extras: [
{ name: 'lastComments', type: 'Int', defaultValue: 100 },
{ name: 'firstLabels', type: 'Int', defaultValue: 100 },
],
selection: (
index: number,
) => `node${index}: repository(owner: $owner${index}, name: $name${index}) {
issue(number: $number${index}) {
...IssueDetails
}
}`,
} as GraphQLMergedQueryConfig;
}

async enrich(
notification: Notification,
_notification: Notification,
_settings: SettingsState,
fetchedData?: IssueDetailsFragment,
): Promise<GitifySubject> {
const response = await fetchIssueByNumber(notification);
const issue = response.data.repository?.issue;
const issue = fetchedData;

const issueState = issue.stateReason ?? issue.state;

Expand Down
30 changes: 27 additions & 3 deletions src/renderer/utils/notifications/handlers/pullRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,43 @@ import {
} from '../../../types';
import type { Notification, Subject } from '../../../typesGitHub';
import { fetchPullByNumber } from '../../api/client';
import type { PullRequestReviewFieldsFragment } from '../../api/graphql/generated/graphql';
import {
type PullRequestDetailsFragment,
PullRequestDetailsFragmentDoc,
PullRequestMergeQueryFragmentDoc,
type PullRequestReviewFieldsFragment,
} from '../../api/graphql/generated/graphql';
import { getQueryFragmentBody } from '../../api/graphql/utils';
import { DefaultHandler, defaultHandler } from './default';
import type { GraphQLMergedQueryConfig } from './types';
import { getNotificationAuthor } from './utils';

class PullRequestHandler extends DefaultHandler {
readonly type = 'PullRequest' as const;

mergeQueryConfig() {
return {
queryFragment: getQueryFragmentBody(
PullRequestMergeQueryFragmentDoc.toString(),
),
responseFragment: PullRequestDetailsFragmentDoc.toString(),
extras: [
{ name: 'firstLabels', type: 'Int', defaultValue: 100 },
{ name: 'lastComments', type: 'Int', defaultValue: 100 },
{ name: 'lastReviews', type: 'Int', defaultValue: 100 },
{ name: 'firstClosingIssues', type: 'Int', defaultValue: 100 },
],
} as GraphQLMergedQueryConfig;
}

async enrich(
notification: Notification,
_settings: SettingsState,
fetchedData?: PullRequestDetailsFragment,
): Promise<GitifySubject> {
const response = await fetchPullByNumber(notification);
const pr = response.data.repository.pullRequest;
const pr =
fetchedData ??
(await fetchPullByNumber(notification)).data.nodeINDEX.pullRequest;

let prState: GitifyPullRequestState = pr.state;
if (pr.isDraft) {
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/utils/notifications/handlers/release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getNotificationAuthor } from './utils';
class ReleaseHandler extends DefaultHandler {
readonly type = 'Release';

async enrich(
async fetchAndEnrich(
notification: Notification,
settings: SettingsState,
): Promise<GitifySubject> {
Expand Down
27 changes: 25 additions & 2 deletions src/renderer/utils/notifications/handlers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,38 @@ import type { OcticonProps } from '@primer/octicons-react';
import type { GitifySubject, Link, SettingsState } from '../../../types';
import type { Notification, Subject, SubjectType } from '../../../typesGitHub';

export interface NotificationTypeHandler {
export type GraphQLMergedQueryConfig = {
queryFragment: string;
responseFragment: string;
extras: Array<{
name: string;
type: string;
defaultValue: number | boolean;
}>;
};

export interface NotificationTypeHandler<TFragment = unknown> {
readonly type?: SubjectType;

mergeQueryConfig(): GraphQLMergedQueryConfig;

query(notification: Notification): { query; variables } | null;

/**
* Fetch remote data (if needed) and enrich a notification.
*/
fetchAndEnrich(
notification: Notification,
settings: SettingsState,
): Promise<GitifySubject>;

/**
* Enrich a notification. Settings may be unused for some handlers.
*/
enrich(
notification: Notification,
settings: SettingsState,
settings?: SettingsState,
fetchedData?: TFragment,
): Promise<GitifySubject>;

/**
Expand Down
Loading
Loading