Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: biome linter updates #1226

Merged
merged 7 commits into from
Jun 14, 2024
Merged
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
4 changes: 4 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"enabled": true,
"rules": {
"recommended": true,
"nursery": {
"noUnusedFunctionParameters": "error",
"useDefaultSwitchClause": "error"
},
"correctness": {
"useExhaustiveDependencies": {
"level": "warn",
Expand Down
2 changes: 1 addition & 1 deletion src/__mocks__/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module.exports = {
send: jest.fn(),
on: jest.fn(),
sendSync: jest.fn(),
invoke: jest.fn((channel, ...args) => {
invoke: jest.fn((channel, ..._args) => {
switch (channel) {
case 'get-platform':
return Promise.resolve('darwin');
Expand Down
1 change: 0 additions & 1 deletion src/components/AccountNotifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export const AccountNotifications = (props: IProps) => {
return (
<RepositoryNotifications
key={repoSlug}
account={account}
repoName={repoSlug}
repoNotifications={repoNotifications}
/>
Expand Down
15 changes: 8 additions & 7 deletions src/components/NotificationRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
useState,
} from 'react';
import { AppContext } from '../context/App';
import { type Account, IconColor } from '../types';
import { IconColor } from '../types';
import type { Notification } from '../typesGitHub';
import { cn } from '../utils/cn';
import {
Expand All @@ -33,19 +33,16 @@ import { formatReason } from '../utils/reason';
import { PillButton } from './buttons/PillButton';

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

export const NotificationRow: FC<IProps> = ({ notification, account }) => {
export const NotificationRow: FC<IProps> = ({ notification }) => {
const {
auth,
settings,
removeNotificationFromState,
markNotificationRead,
markNotificationDone,
unsubscribeNotification,
notifications,
} = useContext(AppContext);
const [animateExit, setAnimateExit] = useState(false);

Expand All @@ -59,8 +56,12 @@ export const NotificationRow: FC<IProps> = ({ notification, account }) => {
// no need to mark as read, github does it by default when opening it
removeNotificationFromState(settings, notification);
}
}, [notifications, notification, auth, settings]); // notifications required here to prevent weird state issues
bmulholland marked this conversation as resolved.
Show resolved Hide resolved

}, [
notification,
markNotificationDone,
removeNotificationFromState,
settings,
]);
const unsubscribeFromThread = (event: MouseEvent<HTMLElement>) => {
// Don't trigger onClick of parent element.
event.stopPropagation();
Expand Down
9 changes: 3 additions & 6 deletions src/components/Repository.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
import { CheckIcon, MarkGithubIcon, ReadIcon } from '@primer/octicons-react';
import { type FC, useCallback, useContext } from 'react';
import { AppContext } from '../context/App';
import type { Account } from '../types';
import type { Notification } from '../typesGitHub';
import { openRepository } from '../utils/links';
import { NotificationRow } from './NotificationRow';

interface IProps {
account: Account;
repoNotifications: Notification[];
repoName: string;
}

export const RepositoryNotifications: FC<IProps> = ({
repoName,
repoNotifications,
account,
}) => {
const { markRepoNotificationsRead, markRepoNotificationsDone } =
useContext(AppContext);

const markRepoAsRead = useCallback(() => {
markRepoNotificationsRead(repoNotifications[0]);
}, [repoNotifications, account]);
}, [repoNotifications, markRepoNotificationsRead]);

const markRepoAsDone = useCallback(() => {
markRepoNotificationsDone(repoNotifications[0]);
}, [repoNotifications, account]);
}, [repoNotifications, markRepoNotificationsDone]);

const avatarUrl = repoNotifications[0].repository.owner.avatar_url;
const repoSlug = repoNotifications[0].repository.full_name;
Expand Down Expand Up @@ -77,7 +74,7 @@ export const RepositoryNotifications: FC<IProps> = ({
</div>

{repoNotifications.map((obj) => (
<NotificationRow key={obj.id} account={account} notification={obj} />
<NotificationRow key={obj.id} notification={obj} />
))}
</>
);
Expand Down
13 changes: 6 additions & 7 deletions src/context/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
fetchNotifications({ auth, settings });
}, Constants.FETCH_INTERVAL);

// biome-ignore lint/correctness/useExhaustiveDependencies: We need to update tray title when settings or notifications changes.
useEffect(() => {
const count = getNotificationCount(notifications);

Expand Down Expand Up @@ -227,37 +226,37 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {

const fetchNotificationsWithAccounts = useCallback(
async () => await fetchNotifications({ auth, settings }),
[auth, settings, notifications],
[auth, settings, fetchNotifications],
);

const markNotificationReadWithAccounts = useCallback(
async (notification: Notification) =>
await markNotificationRead({ auth, settings }, notification),
[auth, notifications],
[auth, settings, markNotificationRead],
);

const markNotificationDoneWithAccounts = useCallback(
async (notification: Notification) =>
await markNotificationDone({ auth, settings }, notification),
[auth, notifications],
[auth, settings, markNotificationDone],
);

const unsubscribeNotificationWithAccounts = useCallback(
async (notification: Notification) =>
await unsubscribeNotification({ auth, settings }, notification),
[auth, notifications],
[auth, settings, unsubscribeNotification],
);

const markRepoNotificationsReadWithAccounts = useCallback(
async (notification: Notification) =>
await markRepoNotificationsRead({ auth, settings }, notification),
[auth, notifications],
[auth, settings, markRepoNotificationsRead],
);

const markRepoNotificationsDoneWithAccounts = useCallback(
async (notification: Notification) =>
await markRepoNotificationsDone({ auth, settings }, notification),
[auth, notifications],
[auth, settings, markRepoNotificationsDone],
);

return (
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/useNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ export const useNotifications = (): NotificationsState => {
setStatus('success');
}
},
[notifications],
[markNotificationRead],
);

const markRepoNotificationsRead = useCallback(
async (state: GitifyState, notification: Notification) => {
async (_state: GitifyState, notification: Notification) => {
setStatus('loading');

const repoSlug = notification.repository.full_name;
Expand Down Expand Up @@ -220,7 +220,7 @@ export const useNotifications = (): NotificationsState => {
setStatus('success');
}
},
[notifications],
[notifications, markNotificationDone],
);

const removeNotificationFromState = useCallback(
Expand Down
15 changes: 9 additions & 6 deletions src/routes/Accounts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ export const AccountsRoute: FC = () => {
const { auth, logoutFromAccount } = useContext(AppContext);
const navigate = useNavigate();

const logoutAccount = useCallback((account: Account) => {
logoutFromAccount(account);
navigate(-1);
updateTrayIcon();
updateTrayTitle();
}, []);
const logoutAccount = useCallback(
(account: Account) => {
logoutFromAccount(account);
navigate(-1);
updateTrayIcon();
updateTrayTitle();
},
[logoutFromAccount],
);

const loginWithPersonalAccessToken = useCallback(() => {
return navigate('/login-personal-access-token', { replace: true });
Expand Down
17 changes: 10 additions & 7 deletions src/routes/LoginWithOAuthApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,16 @@ export const LoginWithOAuthApp: FC = () => {
);
};

const login = useCallback(async (data: IValues) => {
try {
await loginWithOAuthApp(data as LoginOAuthAppOptions);
} catch (err) {
// Skip
}
}, []);
const login = useCallback(
async (data: IValues) => {
try {
await loginWithOAuthApp(data as LoginOAuthAppOptions);
} catch (err) {
// Skip
}
},
[loginWithOAuthApp],
);

return (
<div className="flex-1 bg-white dark:bg-gray-dark dark:text-white">
Expand Down
25 changes: 14 additions & 11 deletions src/routes/LoginWithPersonalAccessToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,20 @@ export const LoginWithPersonalAccessToken: FC = () => {
);
};

const login = useCallback(async (data: IValues) => {
setIsValidToken(true);
try {
await loginWithPersonalAccessToken(
data as LoginPersonalAccessTokenOptions,
);
navigate(-1);
} catch (err) {
setIsValidToken(false);
}
}, []);
const login = useCallback(
async (data: IValues) => {
setIsValidToken(true);
try {
await loginWithPersonalAccessToken(
data as LoginPersonalAccessTokenOptions,
);
navigate(-1);
} catch (err) {
setIsValidToken(false);
}
},
[loginWithPersonalAccessToken],
);

return (
<div className="flex-1 bg-white dark:bg-gray-dark dark:text-white">
Expand Down
10 changes: 10 additions & 0 deletions src/utils/auth/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { AxiosPromise, AxiosResponse } from 'axios';
import { mockAuth, mockGitHubCloudAccount } from '../../__mocks__/state-mocks';
import type { Account, AuthState } from '../../types';
import * as apiRequests from '../api/request';
import type { AuthMethod } from './types';
import * as auth from './utils';
import { getNewOAuthAppURL, getNewTokenURL } from './utils';

Expand Down Expand Up @@ -222,18 +223,27 @@ describe('utils/auth/utils.ts', () => {
method: 'GitHub App',
} as Account),
).toBe('https://github.com/settings/apps');

expect(
auth.getDeveloperSettingsURL({
hostname: 'github.com',
method: 'OAuth App',
} as Account),
).toBe('https://github.com/settings/developers');

expect(
auth.getDeveloperSettingsURL({
hostname: 'github.com',
method: 'Personal Access Token',
} as Account),
).toBe('https://github.com/settings/tokens');

expect(
auth.getDeveloperSettingsURL({
hostname: 'github.com',
method: 'unknown' as AuthMethod,
} as Account),
).toBe('https://github.com/settings');
});

describe('getNewTokenURL', () => {
Expand Down
5 changes: 4 additions & 1 deletion src/utils/auth/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const authGitHub = (

authWindow.webContents.on(
'did-fail-load',
(event, errorCode, errorDescription, validatedURL) => {
(_event, _errorCode, _errorDescription, validatedURL) => {
if (validatedURL.includes(authOptions.hostname)) {
authWindow.destroy();
reject(
Expand Down Expand Up @@ -151,6 +151,9 @@ export function getDeveloperSettingsURL(account: Account): string {
case 'Personal Access Token':
settingsURL.pathname = '/settings/tokens';
break;
default:
settingsURL.pathname = '/settings';
break;
}
return settingsURL.toString();
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/theme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('utils/theme.ts', () => {
it("should use the system's mode - light", () => {
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
value: jest.fn().mockImplementation((_query) => ({
matches: false,
})),
});
Expand All @@ -32,7 +32,7 @@ describe('utils/theme.ts', () => {
it("should use the system's mode - dark", () => {
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
value: jest.fn().mockImplementation((_query) => ({
matches: true,
})),
});
Expand Down