From d87ef3ccf61e497d676e1f0af4048a5d0df66e2f Mon Sep 17 00:00:00 2001 From: zhom <2717306+zhom@users.noreply.github.com> Date: Thu, 29 May 2025 11:00:19 +0400 Subject: [PATCH] chore: simplify js linting --- .github/workflows/lint-js.yml | 5 ++ .prettierignore | 7 ++ .prettierrc | 8 ++ biome.json | 53 ------------- eslint.config.mjs | 10 +-- nodecar/eslint.config.mjs | 10 +-- package.json | 5 +- pnpm-lock.yaml | 91 ---------------------- src/app/page.tsx | 42 +++++----- src/components/change-version-dialog.tsx | 4 +- src/components/create-profile-dialog.tsx | 8 +- src/components/custom-toast.tsx | 12 +-- src/components/profile-data-table.tsx | 10 +-- src/components/profile-selector-dialog.tsx | 14 ++-- src/components/theme-provider.tsx | 4 +- src/components/ui/alert.tsx | 6 +- src/components/ui/badge.tsx | 2 +- src/components/ui/button.tsx | 2 +- src/components/ui/card.tsx | 6 +- src/components/ui/checkbox.tsx | 2 +- src/components/ui/combobox.tsx | 2 +- src/components/ui/command.tsx | 12 +-- src/components/ui/dialog.tsx | 6 +- src/components/ui/dropdown-menu.tsx | 16 ++-- src/components/ui/input.tsx | 2 +- src/components/ui/label.tsx | 2 +- src/components/ui/popover.tsx | 2 +- src/components/ui/progress.tsx | 2 +- src/components/ui/scroll-area.tsx | 2 +- src/components/ui/select.tsx | 12 +-- src/components/ui/table.tsx | 8 +- src/components/ui/tooltip.tsx | 2 +- src/components/update-notification.tsx | 16 ++-- src/components/version-selector.tsx | 6 +- src/hooks/use-browser-download.ts | 28 +++---- src/hooks/use-table-sorting.ts | 6 +- src/hooks/use-version-updater.ts | 24 +++--- 37 files changed, 162 insertions(+), 287 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc delete mode 100644 biome.json diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index 8a8e793..f60c72c 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -40,5 +40,10 @@ jobs: - name: Install dependencies from lockfile run: pnpm install --frozen-lockfile + - name: Install nodecar dependencies + run: | + cd nodecar + pnpm install --frozen-lockfile + - name: Run lint step run: pnpm lint diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..4fe8af3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +node_modules/ +dist/ +.next/ +src-tauri/target/ +*.lock +pnpm-lock.yaml +*.log \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..2eef55d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false +} diff --git a/biome.json b/biome.json deleted file mode 100644 index c7952bb..0000000 --- a/biome.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "vcs": { - "enabled": false, - "clientKind": "git", - "useIgnoreFile": false - }, - "files": { - "ignoreUnknown": false, - "ignore": [] - }, - "formatter": { - "enabled": true, - "indentStyle": "space", - "indentWidth": 2 - }, - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "correctness": { - "useHookAtTopLevel": "error" - }, - "nursery": { - "useGoogleFontDisplay": "error", - "noDocumentImportInPage": "error", - "noHeadElement": "error", - "noHeadImportInDocument": "error", - "noImgElement": "off", - "useComponentExportOnlyModules": { - "level": "error", - "options": { - "allowExportNames": ["metadata"] - } - } - } - } - }, - "css": { - "formatter": { - "quoteStyle": "double" - } - }, - "javascript": { - "formatter": { - "quoteStyle": "double" - }, - "globals": [] - } -} diff --git a/eslint.config.mjs b/eslint.config.mjs index 5e3bedb..47b9b0c 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -13,9 +13,9 @@ const eslintConfig = tseslint.config( ...compat.extends("next/core-web-vitals"), { // Disabled rules taken from https://biomejs.dev/linter/rules-sources for ones that - // are already handled by Biome + // are already handled by Prettier and TypeScript or are not needed rules: { - // eslint-plugin-jsx-a11y rules replaced by Biome + // eslint-plugin-jsx-a11y rules - some disabled for performance/specific project needs "jsx-a11y/alt-text": "off", "jsx-a11y/anchor-has-content": "off", "jsx-a11y/anchor-is-valid": "off", @@ -49,7 +49,7 @@ const eslintConfig = tseslint.config( "jsx-a11y/role-supports-aria-props": "off", "jsx-a11y/scope": "off", "jsx-a11y/tabindex-no-positive": "off", - // eslint-plugin-react rules replaced by Biome + // eslint-plugin-react rules - some disabled for performance/specific project needs "react/button-has-type": "off", "react/jsx-boolean-value": "off", "react/jsx-curly-brace-presence": "off", @@ -64,10 +64,10 @@ const eslintConfig = tseslint.config( "react/no-danger": "off", "react/no-danger-with-children": "off", "react/void-dom-elements-no-children": "off", - // eslint-plugin-react-hooks rules replaced by Biome + // eslint-plugin-react-hooks rules - disabled for specific project needs "react-hooks/exhaustive-deps": "off", "react-hooks/rules-of-hooks": "off", - // typescript-eslint rules replaced by Biome + // typescript-eslint rules - some handled by TypeScript compiler or disabled for project needs "@typescript-eslint/adjacent-overload-signatures": "off", "@typescript-eslint/array-type": "off", "@typescript-eslint/ban-types": "off", diff --git a/nodecar/eslint.config.mjs b/nodecar/eslint.config.mjs index ad226f2..b5f8cc0 100644 --- a/nodecar/eslint.config.mjs +++ b/nodecar/eslint.config.mjs @@ -11,9 +11,9 @@ const eslintConfig = tseslint.config( ...compat.extends("next/core-web-vitals"), { // Disabled rules taken from https://biomejs.dev/linter/rules-sources for ones that - // are already handled by Biome + // are already handled by Prettier and TypeScript or are not needed rules: { - // eslint-plugin-jsx-a11y rules replaced by Biome + // eslint-plugin-jsx-a11y rules - some disabled for performance/specific project needs "jsx-a11y/alt-text": "off", "jsx-a11y/anchor-has-content": "off", "jsx-a11y/anchor-is-valid": "off", @@ -47,7 +47,7 @@ const eslintConfig = tseslint.config( "jsx-a11y/role-supports-aria-props": "off", "jsx-a11y/scope": "off", "jsx-a11y/tabindex-no-positive": "off", - // eslint-plugin-react rules replaced by Biome + // eslint-plugin-react rules - some disabled for performance/specific project needs "react/button-has-type": "off", "react/jsx-boolean-value": "off", "react/jsx-curly-brace-presence": "off", @@ -62,10 +62,10 @@ const eslintConfig = tseslint.config( "react/no-danger": "off", "react/no-danger-with-children": "off", "react/void-dom-elements-no-children": "off", - // eslint-plugin-react-hooks rules replaced by Biome + // eslint-plugin-react-hooks rules - disabled for specific project needs "react-hooks/exhaustive-deps": "off", "react-hooks/rules-of-hooks": "off", - // typescript-eslint rules replaced by Biome + // typescript-eslint rules - some handled by TypeScript compiler or disabled for project needs "@typescript-eslint/adjacent-overload-signatures": "off", "@typescript-eslint/array-type": "off", "@typescript-eslint/ban-types": "off", diff --git a/package.json b/package.json index 4c62498..dba3206 100644 --- a/package.json +++ b/package.json @@ -7,11 +7,11 @@ "dev": "next dev --turbopack", "build": "next build", "start": "next start", - "lint": "biome check src/ && next lint", + "lint": "prettier --check src/ && tsc --noEmit && next lint", "tauri": "tauri", "shadcn:add": "pnpm dlx shadcn@latest add", "prepare": "husky", - "format:js": "biome format --write src/", + "format:js": "prettier --write src/", "format:rust": "cd src-tauri && cargo fmt --all", "format": "pnpm format:js && pnpm format:rust", "prettier": "prettier --write" @@ -43,7 +43,6 @@ "tailwind-merge": "^3.3.0" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.27.0", "@next/eslint-plugin-next": "^15.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d301598..b9b055a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -81,9 +81,6 @@ importers: specifier: ^3.3.0 version: 3.3.0 devDependencies: - '@biomejs/biome': - specifier: ^1.9.4 - version: 1.9.4 '@eslint/eslintrc': specifier: ^3.3.1 version: 3.3.1 @@ -237,59 +234,6 @@ packages: resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} - '@biomejs/biome@1.9.4': - resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} - engines: {node: '>=14.21.3'} - hasBin: true - - '@biomejs/cli-darwin-arm64@1.9.4': - resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [darwin] - - '@biomejs/cli-darwin-x64@1.9.4': - resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [darwin] - - '@biomejs/cli-linux-arm64-musl@1.9.4': - resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [linux] - - '@biomejs/cli-linux-arm64@1.9.4': - resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [linux] - - '@biomejs/cli-linux-x64-musl@1.9.4': - resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [linux] - - '@biomejs/cli-linux-x64@1.9.4': - resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [linux] - - '@biomejs/cli-win32-arm64@1.9.4': - resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [win32] - - '@biomejs/cli-win32-x64@1.9.4': - resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [win32] - '@emnapi/core@1.4.3': resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} @@ -3285,41 +3229,6 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@biomejs/biome@1.9.4': - optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.4 - '@biomejs/cli-darwin-x64': 1.9.4 - '@biomejs/cli-linux-arm64': 1.9.4 - '@biomejs/cli-linux-arm64-musl': 1.9.4 - '@biomejs/cli-linux-x64': 1.9.4 - '@biomejs/cli-linux-x64-musl': 1.9.4 - '@biomejs/cli-win32-arm64': 1.9.4 - '@biomejs/cli-win32-x64': 1.9.4 - - '@biomejs/cli-darwin-arm64@1.9.4': - optional: true - - '@biomejs/cli-darwin-x64@1.9.4': - optional: true - - '@biomejs/cli-linux-arm64-musl@1.9.4': - optional: true - - '@biomejs/cli-linux-arm64@1.9.4': - optional: true - - '@biomejs/cli-linux-x64-musl@1.9.4': - optional: true - - '@biomejs/cli-linux-x64@1.9.4': - optional: true - - '@biomejs/cli-win32-arm64@1.9.4': - optional: true - - '@biomejs/cli-win32-x64@1.9.4': - optional: true - '@emnapi/core@1.4.3': dependencies: '@emnapi/wasi-threads': 1.0.2 diff --git a/src/app/page.tsx b/src/app/page.tsx index 1135a60..8f6bbe6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -63,7 +63,7 @@ export default function Home() { try { const profileList = await invoke( - "list_browser_profiles", + "list_browser_profiles" ); setProfiles(profileList); @@ -94,7 +94,7 @@ export default function Home() { () => { void checkForUpdates(); }, - 30 * 60 * 1000, + 30 * 60 * 1000 ); return () => { @@ -107,7 +107,7 @@ export default function Home() { try { const shouldShow = await invoke( - "should_show_settings_on_startup", + "should_show_settings_on_startup" ); if (shouldShow) { setSettingsDialogOpen(true); @@ -122,7 +122,7 @@ export default function Home() { try { const hasStartupUrl = await invoke( - "check_and_handle_startup_url", + "check_and_handle_startup_url" ); if (hasStartupUrl) { console.log("Handled startup URL successfully"); @@ -155,10 +155,10 @@ export default function Home() { await listen("show-create-profile-dialog", (event) => { console.log( "Received show create profile dialog request:", - event.payload, + event.payload ); setError( - "No profiles available. Please create a profile first before opening URLs.", + "No profiles available. Please create a profile first before opening URLs." ); setCreateProfileDialogOpen(true); }); @@ -180,7 +180,7 @@ export default function Home() { } catch (error: any) { console.log( "Smart URL opening failed or requires profile selection:", - error, + error ); // Check if it's the special error cases @@ -190,7 +190,7 @@ export default function Home() { } else if (error === "no_profiles") { // No profiles available, show error message setError( - "No profiles available. Please create a profile first before opening URLs.", + "No profiles available. Please create a profile first before opening URLs." ); } else { // Some other error occurred @@ -228,7 +228,7 @@ export default function Home() { setError(`Failed to update proxy settings: ${JSON.stringify(err)}`); } }, - [currentProfileForProxy, loadProfiles], + [currentProfileForProxy, loadProfiles] ); const handleCreateProfile = useCallback( @@ -247,7 +247,7 @@ export default function Home() { name: profileData.name, browserStr: profileData.browserStr, version: profileData.version, - }, + } ); // Update proxy if provided @@ -264,11 +264,11 @@ export default function Home() { throw error; } }, - [loadProfiles], + [loadProfiles] ); const [runningProfiles, setRunningProfiles] = useState>( - new Set(), + new Set() ); const runningProfilesRef = useRef>(new Set()); @@ -300,7 +300,7 @@ export default function Home() { console.error("Failed to check browser status:", err); } }, - [isClient], + [isClient] ); const launchProfile = useCallback( @@ -315,12 +315,12 @@ export default function Home() { "is_browser_disabled_for_update", { browser: profile.browser, - }, + } ); if (isDisabled || isUpdating(profile.browser)) { setError( - `${profile.browser} is currently being updated. Please wait for the update to complete.`, + `${profile.browser} is currently being updated. Please wait for the update to complete.` ); return; } @@ -331,7 +331,7 @@ export default function Home() { try { const updatedProfile = await invoke( "launch_browser_profile", - { profile }, + { profile } ); await loadProfiles(); await checkBrowserStatus(updatedProfile); @@ -340,7 +340,7 @@ export default function Home() { setError(`Failed to launch browser: ${JSON.stringify(err)}`); } }, - [loadProfiles, checkBrowserStatus, isUpdating, isClient], + [loadProfiles, checkBrowserStatus, isUpdating, isClient] ); useEffect(() => { @@ -379,7 +379,7 @@ export default function Home() { setError(`Failed to delete profile: ${JSON.stringify(err)}`); } }, - [loadProfiles], + [loadProfiles] ); const handleRenameProfile = useCallback( @@ -394,7 +394,7 @@ export default function Home() { throw err; } }, - [loadProfiles], + [loadProfiles] ); const handleKillProfile = useCallback( @@ -408,7 +408,7 @@ export default function Home() { setError(`Failed to kill browser: ${JSON.stringify(err)}`); } }, - [loadProfiles], + [loadProfiles] ); // Don't render anything until we're on the client side to prevent hydration issues @@ -554,7 +554,7 @@ export default function Home() { isOpen={true} onClose={() => { setPendingUrls((prev) => - prev.filter((u) => u.id !== pendingUrl.id), + prev.filter((u) => u.id !== pendingUrl.id) ); }} url={pendingUrl.url} diff --git a/src/components/change-version-dialog.tsx b/src/components/change-version-dialog.tsx index d12dc7f..d23d8a8 100644 --- a/src/components/change-version-dialog.tsx +++ b/src/components/change-version-dialog.tsx @@ -60,10 +60,10 @@ export function ChangeVersionDialog({ if (profile && selectedVersion) { // Check if this is a downgrade const currentVersionIndex = availableVersions.findIndex( - (v) => v.tag_name === profile.version, + (v) => v.tag_name === profile.version ); const selectedVersionIndex = availableVersions.findIndex( - (v) => v.tag_name === selectedVersion, + (v) => v.tag_name === selectedVersion ); // If selected version has a higher index, it's older (downgrade) diff --git a/src/components/create-profile-dialog.tsx b/src/components/create-profile-dialog.tsx index b23aeb0..f8927cc 100644 --- a/src/components/create-profile-dialog.tsx +++ b/src/components/create-profile-dialog.tsx @@ -65,7 +65,7 @@ export function CreateProfileDialog({ >([]); const [isCreating, setIsCreating] = useState(false); const [existingProfiles, setExistingProfiles] = useState( - [], + [] ); // Proxy settings @@ -120,7 +120,7 @@ export function CreateProfileDialog({ const loadSupportedBrowsers = async () => { try { const browsers = await invoke( - "get_supported_browsers", + "get_supported_browsers" ); setSupportedBrowsers(browsers); if (browsers.includes("mullvad-browser")) { @@ -156,7 +156,7 @@ export function CreateProfileDialog({ // Check for duplicate names (case insensitive) const isDuplicate = existingProfiles.some( - (profile) => profile.name.toLowerCase() === trimmedName.toLowerCase(), + (profile) => profile.name.toLowerCase() === trimmedName.toLowerCase() ); if (isDuplicate) { @@ -271,7 +271,7 @@ export function CreateProfileDialog({ {browser .split("-") .map( - (word) => word.charAt(0).toUpperCase() + word.slice(1), + (word) => word.charAt(0).toUpperCase() + word.slice(1) ) .join(" ")} diff --git a/src/components/custom-toast.tsx b/src/components/custom-toast.tsx index 18bbcdf..16a0869 100644 --- a/src/components/custom-toast.tsx +++ b/src/components/custom-toast.tsx @@ -298,7 +298,7 @@ export function showLoadingToast( id?: string; description?: string; duration?: number; - }, + } ) { return showToast({ type: "loading", @@ -312,7 +312,7 @@ export function showDownloadToast( version: string, stage: "downloading" | "extracting" | "verifying" | "completed", progress?: { percentage: number; speed?: string; eta?: string }, - options?: { suppressCompletionToast?: boolean }, + options?: { suppressCompletionToast?: boolean } ) { const title = stage === "completed" @@ -349,7 +349,7 @@ export function showVersionUpdateToast( found: number; }; duration?: number; - }, + } ) { return showToast({ type: "version-update", @@ -364,7 +364,7 @@ export function showFetchingToast( id?: string; description?: string; duration?: number; - }, + } ) { return showToast({ type: "fetching", @@ -382,7 +382,7 @@ export function showSuccessToast( id?: string; description?: string; duration?: number; - }, + } ) { return showToast({ type: "success", @@ -397,7 +397,7 @@ export function showErrorToast( id?: string; description?: string; duration?: number; - }, + } ) { return showToast({ type: "error", diff --git a/src/components/profile-data-table.tsx b/src/components/profile-data-table.tsx index ec68c5d..004bd8b 100644 --- a/src/components/profile-data-table.tsx +++ b/src/components/profile-data-table.tsx @@ -101,7 +101,7 @@ export function ProfilesDataTable({ setSorting(newSorting); updateSorting(newSorting); }, - [sorting, updateSorting, isClient], + [sorting, updateSorting, isClient] ); const handleRename = async () => { @@ -131,7 +131,7 @@ export function ProfilesDataTable({ const anyTorRunning = isClient && data.some( - (p) => p.browser === "tor-browser" && runningProfiles.has(p.name), + (p) => p.browser === "tor-browser" && runningProfiles.has(p.name) ); const shouldDisableTorStart = isTorBrowser && !isRunning && anyTorRunning; @@ -392,7 +392,7 @@ export function ProfilesDataTable({ }, }, ], - [isClient, runningProfiles, isUpdating, data], + [isClient, runningProfiles, isUpdating, data] ); const table = useReactTable({ @@ -420,7 +420,7 @@ export function ProfilesDataTable({ ? null : flexRender( header.column.columnDef.header, - header.getContext(), + header.getContext() )} ); @@ -439,7 +439,7 @@ export function ProfilesDataTable({ {flexRender( cell.column.columnDef.cell, - cell.getContext(), + cell.getContext() )} ))} diff --git a/src/components/profile-selector-dialog.tsx b/src/components/profile-selector-dialog.tsx index d998659..e14782a 100644 --- a/src/components/profile-selector-dialog.tsx +++ b/src/components/profile-selector-dialog.tsx @@ -58,7 +58,7 @@ export function ProfileSelectorDialog({ setIsLoading(true); try { const profileList = await invoke( - "list_browser_profiles", + "list_browser_profiles" ); // Sort profiles by name @@ -92,14 +92,14 @@ export function ProfileSelectorDialog({ const canUseProfileForLinks = ( profile: BrowserProfile, allProfiles: BrowserProfile[], - runningProfiles: Set, + runningProfiles: Set ): boolean => { const isRunning = runningProfiles.has(profile.name); // For TOR browser: Check if any TOR browser is running if (profile.browser === "tor-browser") { const runningTorProfiles = allProfiles.filter( - (p) => p.browser === "tor-browser" && runningProfiles.has(p.name), + (p) => p.browser === "tor-browser" && runningProfiles.has(p.name) ); // If no TOR browser is running, allow any TOR profile @@ -126,7 +126,7 @@ export function ProfileSelectorDialog({ if (profile.browser === "tor-browser") { const runningTorProfiles = profiles.filter( - (p) => p.browser === "tor-browser" && runningProfiles.has(p.name), + (p) => p.browser === "tor-browser" && runningProfiles.has(p.name) ); // If another TOR profile is running, this one is not available @@ -192,7 +192,7 @@ export function ProfileSelectorDialog({ return canUseProfileForLinks( selectedProfileData, profiles, - runningProfiles, + runningProfiles ); }; @@ -261,7 +261,7 @@ export function ProfileSelectorDialog({ const canUseForLinks = canUseProfileForLinks( profile, profiles, - runningProfiles, + runningProfiles ); const tooltipContent = getProfileTooltipContent(profile); @@ -281,7 +281,7 @@ export function ProfileSelectorDialog({
{(() => { const IconComponent = getBrowserIcon( - profile.browser, + profile.browser ); return IconComponent ? ( diff --git a/src/components/theme-provider.tsx b/src/components/theme-provider.tsx index 3826c14..59821e5 100644 --- a/src/components/theme-provider.tsx +++ b/src/components/theme-provider.tsx @@ -17,7 +17,7 @@ interface CustomThemeProviderProps { function getSystemTheme(): string { if (typeof window !== "undefined") { const isDarkMode = window.matchMedia( - "(prefers-color-scheme: dark)", + "(prefers-color-scheme: dark)" ).matches; return isDarkMode ? "dark" : "light"; } @@ -39,7 +39,7 @@ export function CustomThemeProvider({ children }: CustomThemeProviderProps) { const systemTheme = getSystemTheme(); console.log( "First-time user detected, applying system theme:", - systemTheme, + systemTheme ); // Save the detected theme as the default diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx index d4700bd..c097ffd 100644 --- a/src/components/ui/alert.tsx +++ b/src/components/ui/alert.tsx @@ -16,7 +16,7 @@ const alertVariants = cva( defaultVariants: { variant: "default", }, - }, + } ); function Alert({ @@ -40,7 +40,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { data-slot="alert-title" className={cn( "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight", - className, + className )} {...props} /> @@ -56,7 +56,7 @@ function AlertDescription({ data-slot="alert-description" className={cn( "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed", - className, + className )} {...props} /> diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index dac19eb..1bfee7d 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -22,7 +22,7 @@ const badgeVariants = cva( defaultVariants: { variant: "default", }, - }, + } ); function Badge({ diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 1d0f7c5..224dc5f 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -32,7 +32,7 @@ const buttonVariants = cva( variant: "default", size: "default", }, - }, + } ); export type ButtonProps = React.ComponentProps<"button"> & diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 13631ed..12fe6bf 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -8,7 +8,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) { data-slot="card" className={cn( "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm", - className, + className )} {...props} /> @@ -21,7 +21,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) { data-slot="card-header" className={cn( "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6", - className, + className )} {...props} /> @@ -54,7 +54,7 @@ function CardAction({ className, ...props }: React.ComponentProps<"div">) { data-slot="card-action" className={cn( "col-start-2 row-span-2 row-start-1 self-start justify-self-end", - className, + className )} {...props} /> diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx index 90b0470..0a0105a 100644 --- a/src/components/ui/checkbox.tsx +++ b/src/components/ui/checkbox.tsx @@ -15,7 +15,7 @@ function Checkbox({ data-slot="checkbox" className={cn( "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50", - className, + className )} {...props} > diff --git a/src/components/ui/combobox.tsx b/src/components/ui/combobox.tsx index 5ea9004..e4a1370 100644 --- a/src/components/ui/combobox.tsx +++ b/src/components/ui/combobox.tsx @@ -79,7 +79,7 @@ export function ComboboxDemo() { {framework.label} diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx index b4f9c26..cf39306 100644 --- a/src/components/ui/command.tsx +++ b/src/components/ui/command.tsx @@ -22,7 +22,7 @@ function Command({ data-slot="command" className={cn( "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md", - className, + className )} {...props} /> @@ -67,7 +67,7 @@ function CommandInput({ data-slot="command-input" className={cn( "placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50", - className, + className )} {...props} /> @@ -84,7 +84,7 @@ function CommandList({ data-slot="command-list" className={cn( "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", - className, + className )} {...props} /> @@ -112,7 +112,7 @@ function CommandGroup({ data-slot="command-group" className={cn( "text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-x-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium overflow-y-scroll", - className, + className )} {...props} /> @@ -141,7 +141,7 @@ function CommandItem({ data-slot="command-item" className={cn( "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} {...props} /> @@ -157,7 +157,7 @@ function CommandShortcut({ data-slot="command-shortcut" className={cn( "text-muted-foreground ml-auto text-xs tracking-widest", - className, + className )} {...props} /> diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index ee2d460..104ba69 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -39,7 +39,7 @@ function DialogOverlay({ data-slot="dialog-overlay" className={cn( "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50", - className, + className )} {...props} /> @@ -58,7 +58,7 @@ function DialogContent({ data-slot="dialog-content" className={cn( "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg", - className, + className )} {...props} > @@ -88,7 +88,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { data-slot="dialog-footer" className={cn( "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", - className, + className )} {...props} /> diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx index 3a6a712..b446c7e 100644 --- a/src/components/ui/dropdown-menu.tsx +++ b/src/components/ui/dropdown-menu.tsx @@ -43,7 +43,7 @@ function DropdownMenuContent({ sideOffset={sideOffset} className={cn( "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md", - className, + className )} {...props} /> @@ -75,7 +75,7 @@ function DropdownMenuItem({ data-variant={variant} className={cn( "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} {...props} /> @@ -93,7 +93,7 @@ function DropdownMenuCheckboxItem({ data-slot="dropdown-menu-checkbox-item" className={cn( "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} checked={checked} {...props} @@ -129,7 +129,7 @@ function DropdownMenuRadioItem({ data-slot="dropdown-menu-radio-item" className={cn( "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} {...props} > @@ -156,7 +156,7 @@ function DropdownMenuLabel({ data-inset={inset} className={cn( "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", - className, + className )} {...props} /> @@ -185,7 +185,7 @@ function DropdownMenuShortcut({ data-slot="dropdown-menu-shortcut" className={cn( "text-muted-foreground ml-auto text-xs tracking-widest", - className, + className )} {...props} /> @@ -212,7 +212,7 @@ function DropdownMenuSubTrigger({ data-inset={inset} className={cn( "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8", - className, + className )} {...props} > @@ -231,7 +231,7 @@ function DropdownMenuSubContent({ data-slot="dropdown-menu-sub-content" className={cn( "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg", - className, + className )} {...props} /> diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index cb0e803..a6fa4b6 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -11,7 +11,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) { "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", - className, + className )} {...props} /> diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx index a3661df..52ca238 100644 --- a/src/components/ui/label.tsx +++ b/src/components/ui/label.tsx @@ -14,7 +14,7 @@ function Label({ data-slot="label" className={cn( "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", - className, + className )} {...props} /> diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx index d68b87a..cf4ae36 100644 --- a/src/components/ui/popover.tsx +++ b/src/components/ui/popover.tsx @@ -31,7 +31,7 @@ function PopoverContent({ sideOffset={sideOffset} className={cn( "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden", - className, + className )} {...props} /> diff --git a/src/components/ui/progress.tsx b/src/components/ui/progress.tsx index d00d550..f17e9a1 100644 --- a/src/components/ui/progress.tsx +++ b/src/components/ui/progress.tsx @@ -15,7 +15,7 @@ function Progress({ data-slot="progress" className={cn( "bg-primary/20 relative h-2 w-full overflow-hidden rounded-full", - className, + className )} {...props} > diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx index 554e349..309a7f6 100644 --- a/src/components/ui/scroll-area.tsx +++ b/src/components/ui/scroll-area.tsx @@ -43,7 +43,7 @@ function ScrollBar({ "h-full w-2.5 border-l border-l-transparent", orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent", - className, + className )} {...props} > diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index a74f8fb..5601a89 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -38,7 +38,7 @@ function SelectTrigger({ data-size={size} className={cn( "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", - className, + className )} {...props} > @@ -64,7 +64,7 @@ function SelectContent({ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", - className, + className )} position={position} {...props} @@ -74,7 +74,7 @@ function SelectContent({ className={cn( "p-1", position === "popper" && - "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1", + "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1" )} > {children} @@ -108,7 +108,7 @@ function SelectItem({ data-slot="select-item" className={cn( "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", - className, + className )} {...props} > @@ -144,7 +144,7 @@ function SelectScrollUpButton({ data-slot="select-scroll-up-button" className={cn( "flex cursor-default items-center justify-center py-1", - className, + className )} {...props} > @@ -162,7 +162,7 @@ function SelectScrollDownButton({ data-slot="select-scroll-down-button" className={cn( "flex cursor-default items-center justify-center py-1", - className, + className )} {...props} > diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx index 430838f..134e7ce 100644 --- a/src/components/ui/table.tsx +++ b/src/components/ui/table.tsx @@ -45,7 +45,7 @@ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { data-slot="table-footer" className={cn( "bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", - className, + className )} {...props} /> @@ -58,7 +58,7 @@ function TableRow({ className, ...props }: React.ComponentProps<"tr">) { data-slot="table-row" className={cn( "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", - className, + className )} {...props} /> @@ -71,7 +71,7 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) { data-slot="table-head" className={cn( "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", - className, + className )} {...props} /> @@ -84,7 +84,7 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) { data-slot="table-cell" className={cn( "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", - className, + className )} {...props} /> diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx index 35a9ba6..43ba229 100644 --- a/src/components/ui/tooltip.tsx +++ b/src/components/ui/tooltip.tsx @@ -47,7 +47,7 @@ function TooltipContent({ sideOffset={sideOffset} className={cn( "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", - className, + className )} {...props} > diff --git a/src/components/update-notification.tsx b/src/components/update-notification.tsx index 0ae918a..1c7727f 100644 --- a/src/components/update-notification.tsx +++ b/src/components/update-notification.tsx @@ -112,7 +112,7 @@ function UpdateNotificationComponent({ export function useUpdateNotifications() { const [notifications, setNotifications] = useState([]); const [updatingBrowsers, setUpdatingBrowsers] = useState>( - new Set(), + new Set() ); const [isClient, setIsClient] = useState(false); @@ -126,7 +126,7 @@ export function useUpdateNotifications() { try { const updates = await invoke( - "check_for_browser_updates", + "check_for_browser_updates" ); setNotifications(updates); @@ -145,7 +145,7 @@ export function useUpdateNotifications() { // Dismiss all notifications for this browser first const browserNotifications = notifications.filter( - (n) => n.browser === browser, + (n) => n.browser === browser ); for (const notification of browserNotifications) { toast.dismiss(notification.id); @@ -164,7 +164,7 @@ export function useUpdateNotifications() { if (isDownloaded) { // Browser already exists, skip download and go straight to profile update console.log( - `${browserDisplayName} ${newVersion} already exists, skipping download`, + `${browserDisplayName} ${newVersion} already exists, skipping download` ); } else { // Mark download as auto-update in the backend for toast suppression @@ -186,7 +186,7 @@ export function useUpdateNotifications() { { browser, newVersion, - }, + } ); // Show success message based on whether profiles were updated @@ -252,7 +252,7 @@ export function useUpdateNotifications() { }); } }, - [notifications, checkForUpdates], + [notifications, checkForUpdates] ); const handleDismiss = useCallback( @@ -267,7 +267,7 @@ export function useUpdateNotifications() { console.error("Failed to dismiss notification:", error); } }, - [checkForUpdates, isClient], + [checkForUpdates, isClient] ); // Separate effect to show toasts when notifications change @@ -292,7 +292,7 @@ export function useUpdateNotifications() { position: "top-right", // Remove transparent styling to fix background issue style: undefined, - }, + } ); }); }, [notifications, updatingBrowsers, handleUpdate, handleDismiss, isClient]); diff --git a/src/components/version-selector.tsx b/src/components/version-selector.tsx index c3a807f..f3ac915 100644 --- a/src/components/version-selector.tsx +++ b/src/components/version-selector.tsx @@ -91,7 +91,7 @@ export function VersionSelector({ {availableVersions.map((version) => { const isDownloaded = downloadedVersions.includes( - version.tag_name, + version.tag_name ); return (
diff --git a/src/hooks/use-browser-download.ts b/src/hooks/use-browser-download.ts index 51e63ca..49e1d6e 100644 --- a/src/hooks/use-browser-download.ts +++ b/src/hooks/use-browser-download.ts @@ -72,7 +72,7 @@ const isAlphaVersion = (version: string): boolean => { export function useBrowserDownload() { const [availableVersions, setAvailableVersions] = useState( - [], + [] ); const [downloadedVersions, setDownloadedVersions] = useState([]); const [isDownloading, setIsDownloading] = useState(false); @@ -128,7 +128,7 @@ export function useBrowserDownload() { undefined, { suppressCompletionToast: isAutoUpdate, - }, + } ); setDownloadProgress(null); } @@ -167,7 +167,7 @@ export function useBrowserDownload() { `Found ${progress.new_versions_found} new browser versions!`, { duration: 3000, - }, + } ); } // Dismiss any update toasts @@ -179,7 +179,7 @@ export function useBrowserDownload() { }); toast.dismiss(); } - }, + } ); return () => { @@ -224,7 +224,7 @@ export function useBrowserDownload() { try { const versionInfos = await invoke( "fetch_browser_versions_cached_first", - { browserStr }, + { browserStr } ); // Convert BrowserVersionInfo to GithubRelease format for compatibility @@ -234,7 +234,7 @@ export function useBrowserDownload() { assets: [], published_at: versionInfo.date, is_alpha: versionInfo.is_prerelease, - }), + }) ); setAvailableVersions(githubReleases); @@ -259,13 +259,13 @@ export function useBrowserDownload() { // Get versions with new count info and cached detailed info const result = await invoke( "fetch_browser_versions_with_count_cached_first", - { browserStr }, + { browserStr } ); // Get detailed version info for compatibility const versionInfos = await invoke( "fetch_browser_versions_cached_first", - { browserStr }, + { browserStr } ); // Convert BrowserVersionInfo to GithubRelease format for compatibility @@ -275,7 +275,7 @@ export function useBrowserDownload() { assets: [], published_at: versionInfo.date, is_alpha: versionInfo.is_prerelease, - }), + }) ); setAvailableVersions(githubReleases); @@ -287,7 +287,7 @@ export function useBrowserDownload() { { duration: 3000, description: `Total available: ${result.total_versions_count} versions`, - }, + } ); } @@ -307,7 +307,7 @@ export function useBrowserDownload() { try { const downloadedVersions = await invoke( "get_downloaded_browser_versions", - { browserStr }, + { browserStr } ); setDownloadedVersions(downloadedVersions); return downloadedVersions; @@ -321,7 +321,7 @@ export function useBrowserDownload() { async ( browserStr: string, version: string, - suppressNotifications = false, + suppressNotifications = false ) => { const browserName = getBrowserDisplayName(browserStr); setIsDownloading(true); @@ -345,14 +345,14 @@ export function useBrowserDownload() { setIsDownloading(false); } }, - [loadDownloadedVersions], + [loadDownloadedVersions] ); const isVersionDownloaded = useCallback( (version: string) => { return downloadedVersions.includes(version); }, - [downloadedVersions], + [downloadedVersions] ); return { diff --git a/src/hooks/use-table-sorting.ts b/src/hooks/use-table-sorting.ts index 35b7c35..7dfeeb8 100644 --- a/src/hooks/use-table-sorting.ts +++ b/src/hooks/use-table-sorting.ts @@ -15,7 +15,7 @@ export function useTableSorting() { const loadSettings = async () => { try { const settings = await invoke( - "get_table_sorting_settings", + "get_table_sorting_settings" ); setSortingSettings(settings); } catch (error) { @@ -39,7 +39,7 @@ export function useTableSorting() { console.error("Failed to save table sorting settings:", error); } }, - [], + [] ); // Convert our settings to tanstack table sorting format @@ -67,7 +67,7 @@ export function useTableSorting() { void saveSortingSettings(newSettings); } }, - [saveSortingSettings, isLoaded], + [saveSortingSettings, isLoaded] ); return { diff --git a/src/hooks/use-version-updater.ts b/src/hooks/use-version-updater.ts index 31578fe..e1edbe7 100644 --- a/src/hooks/use-version-updater.ts +++ b/src/hooks/use-version-updater.ts @@ -61,7 +61,7 @@ export function useVersionUpdater() { total: progress.total_browsers, found: progress.new_versions_found, }, - }, + } ); } else { showLoadingToast("Starting version update check...", { @@ -81,7 +81,7 @@ export function useVersionUpdater() { duration: 4000, description: "Version information has been updated in the background", - }, + } ); } else { toast.success("No new browser versions found", { @@ -103,7 +103,7 @@ export function useVersionUpdater() { description: "Check your internet connection and try again", }); } - }, + } ); return () => { @@ -130,7 +130,7 @@ export function useVersionUpdater() { const loadUpdateStatus = useCallback(async () => { try { const [lastUpdate, timeUntilNext] = await invoke<[number | null, number]>( - "get_version_update_status", + "get_version_update_status" ); setLastUpdateTime(lastUpdate); setTimeUntilNextUpdate(timeUntilNext); @@ -143,18 +143,18 @@ export function useVersionUpdater() { try { setIsUpdating(true); const results = await invoke( - "trigger_manual_version_update", + "trigger_manual_version_update" ); const totalNewVersions = results.reduce( (sum, result) => sum + result.new_versions_count, - 0, + 0 ); const successfulUpdates = results.filter( - (r) => r.updated_successfully, + (r) => r.updated_successfully ).length; const failedUpdates = results.filter( - (r) => !r.updated_successfully, + (r) => !r.updated_successfully ).length; if (failedUpdates > 0) { @@ -194,7 +194,7 @@ export function useVersionUpdater() { try { const result = await invoke( "fetch_browser_versions_with_count", - { browserStr }, + { browserStr } ); // Show notification about new versions if any were found @@ -205,7 +205,7 @@ export function useVersionUpdater() { { duration: 3000, description: `Total available: ${result.total_versions_count} versions`, - }, + } ); } @@ -215,7 +215,7 @@ export function useVersionUpdater() { throw error; } }, - [], + [] ); const formatTimeUntilUpdate = useCallback((seconds: number): string => { @@ -251,7 +251,7 @@ export function useVersionUpdater() { return "Just now"; } }, - [], + [] ); return {