From b16c24976e3ff3920e25f482fd9e696599604692 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 12 Jun 2024 17:47:29 -0400 Subject: [PATCH 1/5] refactor: address biome warnings. add experimental rule from nursery for unusedFnParams --- biome.json | 3 +++ src/__mocks__/electron.js | 2 +- src/components/NotificationRow.tsx | 15 +++++++------ src/components/Repository.tsx | 10 +++------ src/context/App.tsx | 13 +++++------ src/hooks/useNotifications.ts | 6 ++--- src/routes/Accounts.tsx | 15 ++++++++----- src/routes/LoginWithOAuthApp.tsx | 17 ++++++++------ src/routes/LoginWithPersonalAccessToken.tsx | 25 ++++++++++++--------- src/utils/auth/utils.ts | 2 +- src/utils/theme.test.ts | 4 ++-- 11 files changed, 60 insertions(+), 52 deletions(-) diff --git a/biome.json b/biome.json index b417c560c..efb5eb388 100644 --- a/biome.json +++ b/biome.json @@ -7,6 +7,9 @@ "enabled": true, "rules": { "recommended": true, + "nursery": { + "noUnusedFunctionParameters": "error" + }, "correctness": { "useExhaustiveDependencies": { "level": "warn", diff --git a/src/__mocks__/electron.js b/src/__mocks__/electron.js index 89c50b418..7d4f4f34e 100644 --- a/src/__mocks__/electron.js +++ b/src/__mocks__/electron.js @@ -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'); diff --git a/src/components/NotificationRow.tsx b/src/components/NotificationRow.tsx index b4ad71a07..61690c8c1 100644 --- a/src/components/NotificationRow.tsx +++ b/src/components/NotificationRow.tsx @@ -11,7 +11,7 @@ import { import { type FC, type MouseEvent, useCallback, useContext } from 'react'; import { AppContext } from '../context/App'; -import { type Account, IconColor } from '../types'; +import { IconColor } from '../types'; import type { Notification } from '../typesGitHub'; import { formatForDisplay, @@ -27,19 +27,16 @@ import { formatReason } from '../utils/reason'; import { PillButton } from './buttons/PillButton'; interface IProps { - account: Account; notification: Notification; } -export const NotificationRow: FC = ({ notification, account }) => { +export const NotificationRow: FC = ({ notification }) => { const { - auth, settings, removeNotificationFromState, markNotificationRead, markNotificationDone, unsubscribeNotification, - notifications, } = useContext(AppContext); const handleNotification = useCallback(() => { @@ -51,8 +48,12 @@ export const NotificationRow: FC = ({ 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 - + }, [ + notification, // notifications required here to prevent weird state issues + markNotificationDone, + removeNotificationFromState, + settings, + ]); const unsubscribeFromThread = (event: MouseEvent) => { // Don't trigger onClick of parent element. event.stopPropagation(); diff --git a/src/components/Repository.tsx b/src/components/Repository.tsx index 4021ac27e..3a42f6a3a 100644 --- a/src/components/Repository.tsx +++ b/src/components/Repository.tsx @@ -23,11 +23,11 @@ export const RepositoryNotifications: FC = ({ 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; @@ -80,11 +80,7 @@ export const RepositoryNotifications: FC = ({ {repoNotifications.map((obj) => ( - + ))} diff --git a/src/context/App.tsx b/src/context/App.tsx index 04dadd821..c9fa4e19f 100644 --- a/src/context/App.tsx +++ b/src/context/App.tsx @@ -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); @@ -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 ( diff --git a/src/hooks/useNotifications.ts b/src/hooks/useNotifications.ts index d2c54b78b..2b4b604c4 100644 --- a/src/hooks/useNotifications.ts +++ b/src/hooks/useNotifications.ts @@ -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; @@ -220,7 +220,7 @@ export const useNotifications = (): NotificationsState => { setStatus('success'); } }, - [notifications], + [notifications, markNotificationDone], ); const removeNotificationFromState = useCallback( diff --git a/src/routes/Accounts.tsx b/src/routes/Accounts.tsx index 99a84413e..0a1280f07 100644 --- a/src/routes/Accounts.tsx +++ b/src/routes/Accounts.tsx @@ -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 }); diff --git a/src/routes/LoginWithOAuthApp.tsx b/src/routes/LoginWithOAuthApp.tsx index f95c54153..ec3701c9b 100644 --- a/src/routes/LoginWithOAuthApp.tsx +++ b/src/routes/LoginWithOAuthApp.tsx @@ -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 (
diff --git a/src/routes/LoginWithPersonalAccessToken.tsx b/src/routes/LoginWithPersonalAccessToken.tsx index 26b79cea6..cb0597ce5 100644 --- a/src/routes/LoginWithPersonalAccessToken.tsx +++ b/src/routes/LoginWithPersonalAccessToken.tsx @@ -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 (
diff --git a/src/utils/auth/utils.ts b/src/utils/auth/utils.ts index a6c3f2122..d7ded9554 100644 --- a/src/utils/auth/utils.ts +++ b/src/utils/auth/utils.ts @@ -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( diff --git a/src/utils/theme.test.ts b/src/utils/theme.test.ts index 0c54200c4..9018ac869 100644 --- a/src/utils/theme.test.ts +++ b/src/utils/theme.test.ts @@ -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, })), }); @@ -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, })), }); From bf68df92ace8ba6cb1f44ac53a9d45805f7d0359 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 12 Jun 2024 17:51:30 -0400 Subject: [PATCH 2/5] refactor: enable nursery use default switch clause rule --- biome.json | 3 ++- src/components/AccountNotifications.tsx | 1 - src/components/Repository.tsx | 3 --- src/utils/auth/utils.test.ts | 10 ++++++++++ src/utils/auth/utils.ts | 3 +++ 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/biome.json b/biome.json index efb5eb388..8b73637ee 100644 --- a/biome.json +++ b/biome.json @@ -8,7 +8,8 @@ "rules": { "recommended": true, "nursery": { - "noUnusedFunctionParameters": "error" + "noUnusedFunctionParameters": "error", + "useDefaultSwitchClause": "error" }, "correctness": { "useExhaustiveDependencies": { diff --git a/src/components/AccountNotifications.tsx b/src/components/AccountNotifications.tsx index 0bda63707..6bb4cbb39 100644 --- a/src/components/AccountNotifications.tsx +++ b/src/components/AccountNotifications.tsx @@ -54,7 +54,6 @@ export const AccountNotifications = (props: IProps) => { return ( diff --git a/src/components/Repository.tsx b/src/components/Repository.tsx index 3a42f6a3a..500302519 100644 --- a/src/components/Repository.tsx +++ b/src/components/Repository.tsx @@ -2,13 +2,11 @@ import { CheckIcon, MarkGithubIcon, ReadIcon } from '@primer/octicons-react'; import { type FC, useCallback, useContext } from 'react'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; 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; } @@ -16,7 +14,6 @@ interface IProps { export const RepositoryNotifications: FC = ({ repoName, repoNotifications, - account, }) => { const { markRepoNotificationsRead, markRepoNotificationsDone } = useContext(AppContext); diff --git a/src/utils/auth/utils.test.ts b/src/utils/auth/utils.test.ts index f120fd49a..5648a4599 100644 --- a/src/utils/auth/utils.test.ts +++ b/src/utils/auth/utils.test.ts @@ -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'; @@ -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', () => { diff --git a/src/utils/auth/utils.ts b/src/utils/auth/utils.ts index d7ded9554..151b29c5f 100644 --- a/src/utils/auth/utils.ts +++ b/src/utils/auth/utils.ts @@ -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(); } From 25d0638a0d693446ba86a5af727ac46c09334f34 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 12 Jun 2024 17:52:30 -0400 Subject: [PATCH 3/5] biome: remove exhaustive rule options --- biome.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/biome.json b/biome.json index 8b73637ee..131d7be5c 100644 --- a/biome.json +++ b/biome.json @@ -10,14 +10,6 @@ "nursery": { "noUnusedFunctionParameters": "error", "useDefaultSwitchClause": "error" - }, - "correctness": { - "useExhaustiveDependencies": { - "level": "warn", - "options": { - "hooks": [{ "name": "useNavigate", "stableResult": true }] - } - } } } }, From f4b6130b56179bc50b54699ad149fc7439eb6c17 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 12 Jun 2024 18:00:05 -0400 Subject: [PATCH 4/5] revert biome: remove exhaustive rule options --- biome.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/biome.json b/biome.json index 131d7be5c..8b73637ee 100644 --- a/biome.json +++ b/biome.json @@ -10,6 +10,14 @@ "nursery": { "noUnusedFunctionParameters": "error", "useDefaultSwitchClause": "error" + }, + "correctness": { + "useExhaustiveDependencies": { + "level": "warn", + "options": { + "hooks": [{ "name": "useNavigate", "stableResult": true }] + } + } } } }, From ccbc32c4e05bfc78029d684fc3984ba7dc0b71d6 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 12 Jun 2024 21:25:24 -0400 Subject: [PATCH 5/5] remove comment --- src/components/NotificationRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/NotificationRow.tsx b/src/components/NotificationRow.tsx index 61690c8c1..b4503a2be 100644 --- a/src/components/NotificationRow.tsx +++ b/src/components/NotificationRow.tsx @@ -49,7 +49,7 @@ export const NotificationRow: FC = ({ notification }) => { removeNotificationFromState(settings, notification); } }, [ - notification, // notifications required here to prevent weird state issues + notification, markNotificationDone, removeNotificationFromState, settings,