Skip to content

Commit

Permalink
feat: support multiple accounts (#1201)
Browse files Browse the repository at this point in the history
* feat: support multiple accounts

* feat: update header

* refactor: use account uuid

* update snapshots

* feat: correctly raise native notifications

* pass account instead of hostname

* fix

* Merge remote-tracking branch 'origin/main' into refactor/accounts-auth-token

* update tests
  • Loading branch information
setchy committed Jun 10, 2024
1 parent b017186 commit fedbfbe
Show file tree
Hide file tree
Showing 22 changed files with 438 additions and 401 deletions.
27 changes: 24 additions & 3 deletions src/components/AccountNotifications.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { render } from '@testing-library/react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import { mockGitHubCloudAccount } from '../__mocks__/state-mocks';
import { mockGitHubNotifications } from '../utils/api/__mocks__/response-mocks';
import * as links from '../utils/links';
import { AccountNotifications } from './AccountNotifications';

jest.mock('./Repository', () => ({
Expand All @@ -9,7 +11,7 @@ jest.mock('./Repository', () => ({
describe('components/AccountNotifications.tsx', () => {
it('should render itself (github.com with notifications)', () => {
const props = {
hostname: 'github.com',
account: mockGitHubCloudAccount,
notifications: mockGitHubNotifications,
showAccountHostname: true,
};
Expand All @@ -20,12 +22,31 @@ describe('components/AccountNotifications.tsx', () => {

it('should render itself (github.com without notifications)', () => {
const props = {
hostname: 'github.com',
account: mockGitHubCloudAccount,
notifications: [],
showAccountHostname: true,
};

const tree = render(<AccountNotifications {...props} />);
expect(tree).toMatchSnapshot();
});

it('should open profile when clicked', async () => {
const openAccountProfileMock = jest.spyOn(links, 'openAccountProfile');

const props = {
account: mockGitHubCloudAccount,
notifications: [],
showAccountHostname: true,
};

await act(async () => {
render(<AccountNotifications {...props} />);
});

fireEvent.click(screen.getByTitle('Open Profile'));

expect(openAccountProfileMock).toHaveBeenCalledTimes(1);
expect(openAccountProfileMock).toHaveBeenCalledWith(mockGitHubCloudAccount);
});
});
26 changes: 20 additions & 6 deletions src/components/AccountNotifications.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { ChevronDownIcon, ChevronLeftIcon } from '@primer/octicons-react';
import type { Account } from '../types';
import type { Notification } from '../typesGitHub';
import { openAccountProfile } from '../utils/links';
import { RepositoryNotifications } from './Repository';
import { PlatformIcon } from './icons/PlatformIcon';

interface IProps {
hostname: string;
account: Account;
notifications: Notification[];
showAccountHostname: boolean;
}

export const AccountNotifications = (props: IProps) => {
const { hostname, showAccountHostname, notifications } = props;
const { account, showAccountHostname, notifications } = props;

const groupedNotifications = Object.values(
notifications.reduce(
Expand All @@ -28,9 +31,20 @@ export const AccountNotifications = (props: IProps) => {
return (
<>
{showAccountHostname && (
<div className="flex items-center justify-between py-2 px-3 bg-gray-300 dark:bg-gray-darkest dark:text-white text-sm">
{hostname}
<Chevron size={20} />
<div className="flex items-center justify-between py-2 px-3 bg-gray-300 dark:bg-gray-darkest dark:text-white text-sm text-semibold">
<div>
<PlatformIcon type={account.platform} size={16} />
<button
type="button"
title="Open Profile"
onClick={() => openAccountProfile(account)}
>
@{account.user.login}
</button>
</div>
<div>
<Chevron size={20} />
</div>
</div>
)}

Expand All @@ -40,7 +54,7 @@ export const AccountNotifications = (props: IProps) => {
return (
<RepositoryNotifications
key={repoSlug}
hostname={hostname}
account={account}
repoName={repoSlug}
repoNotifications={repoNotifications}
/>
Expand Down
44 changes: 24 additions & 20 deletions src/components/NotificationRow.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { mockAuth, mockSettings } from '../__mocks__/state-mocks';
import {
mockAuth,
mockGitHubCloudAccount,
mockSettings,
} from '../__mocks__/state-mocks';
import { AppContext } from '../context/App';
import type { Milestone, UserType } from '../typesGitHub';
import { mockSingleNotification } from '../utils/api/__mocks__/response-mocks';
Expand All @@ -23,7 +27,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -44,7 +48,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -65,7 +69,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -88,7 +92,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -115,7 +119,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -140,7 +144,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -167,7 +171,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -192,7 +196,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -217,7 +221,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -244,7 +248,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand Down Expand Up @@ -274,7 +278,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand Down Expand Up @@ -302,7 +306,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

const tree = render(
Expand All @@ -325,7 +329,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand All @@ -350,7 +354,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand All @@ -375,7 +379,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand All @@ -400,7 +404,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand All @@ -423,7 +427,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand All @@ -443,7 +447,7 @@ describe('components/NotificationRow.tsx', () => {

const props = {
notification: mockSingleNotification,
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand Down Expand Up @@ -477,7 +481,7 @@ describe('components/NotificationRow.tsx', () => {
reviews: null,
},
},
hostname: 'github.com',
account: mockGitHubCloudAccount,
};

render(
Expand Down
16 changes: 8 additions & 8 deletions src/components/NotificationRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { type FC, type MouseEvent, useCallback, useContext } from 'react';

import { AppContext } from '../context/App';
import { PILL_CLASS_NAME } from '../styles/gitify';
import { IconColor } from '../types';
import { type Account, IconColor } from '../types';
import type { Notification } from '../typesGitHub';
import {
formatForDisplay,
Expand All @@ -27,11 +27,11 @@ import { openNotification, openUserProfile } from '../utils/links';
import { formatReason } from '../utils/reason';

interface IProps {
hostname: string;
account: Account;
notification: Notification;
}

export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
export const NotificationRow: FC<IProps> = ({ notification, account }) => {
const {
auth,
settings,
Expand All @@ -46,18 +46,18 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
openNotification(notification);

if (settings.markAsDoneOnOpen) {
markNotificationDone(notification.id, hostname);
markNotificationDone(notification);
} else {
// no need to mark as read, github does it by default when opening it
removeNotificationFromState(settings, notification.id, hostname);
removeNotificationFromState(settings, notification);
}
}, [notifications, notification, auth, settings]); // notifications required here to prevent weird state issues

const unsubscribeFromThread = (event: MouseEvent<HTMLElement>) => {
// Don't trigger onClick of parent element.
event.stopPropagation();

unsubscribeNotification(notification.id, hostname);
unsubscribeNotification(notification);
};

const reason = formatReason(notification.reason);
Expand Down Expand Up @@ -225,7 +225,7 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
type="button"
className="focus:outline-none h-full hover:text-green-500"
title="Mark as Done"
onClick={() => markNotificationDone(notification.id, hostname)}
onClick={() => markNotificationDone(notification)}
>
<CheckIcon size={16} aria-label="Mark as Done" />
</button>
Expand All @@ -243,7 +243,7 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
type="button"
className="focus:outline-none h-full hover:text-green-500"
title="Mark as Read"
onClick={() => markNotificationRead(notification.id, hostname)}
onClick={() => markNotificationRead(notification)}
>
<ReadIcon size={14} aria-label="Mark as Read" />
</button>
Expand Down
14 changes: 8 additions & 6 deletions src/components/Repository.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { mockGitHubCloudAccount } from '../__mocks__/state-mocks';
import { AppContext } from '../context/App';
import { mockGitHubNotifications } from '../utils/api/__mocks__/response-mocks';
import {
mockGitHubNotifications,
mockSingleNotification,
} from '../utils/api/__mocks__/response-mocks';
import * as comms from '../utils/comms';
import { RepositoryNotifications } from './Repository';

Expand All @@ -13,7 +17,7 @@ describe('components/Repository.tsx', () => {
const markRepoNotificationsDone = jest.fn();

const props = {
hostname: 'github.com',
account: mockGitHubCloudAccount,
repoName: 'gitify-app/notifications-test',
repoNotifications: mockGitHubNotifications,
};
Expand Down Expand Up @@ -58,8 +62,7 @@ describe('components/Repository.tsx', () => {
fireEvent.click(screen.getByTitle('Mark Repository as Read'));

expect(markRepoNotificationsRead).toHaveBeenCalledWith(
'gitify-app/notifications-test',
'github.com',
mockSingleNotification,
);
});

Expand All @@ -73,8 +76,7 @@ describe('components/Repository.tsx', () => {
fireEvent.click(screen.getByTitle('Mark Repository as Done'));

expect(markRepoNotificationsDone).toHaveBeenCalledWith(
'gitify-app/notifications-test',
'github.com',
mockSingleNotification,
);
});

Expand Down
Loading

0 comments on commit fedbfbe

Please sign in to comment.