From ee8c6dcc85a1cb50f3b9bbf598017c6f199bdafa Mon Sep 17 00:00:00 2001 From: zhom <2717306+zhom@users.noreply.github.com> Date: Tue, 17 Jun 2025 16:13:17 +0400 Subject: [PATCH] chore: add checks for unused ts exports --- package.json | 2 + pnpm-lock.yaml | 15 +++ src-tauri/src/browser_runner.rs | 1 + src/components/update-notification.tsx | 107 ----------------- src/components/version-selector.tsx | 156 ------------------------- src/hooks/use-browser-support.ts | 6 - src/hooks/use-permissions.ts | 2 +- src/lib/browser-utils.ts | 11 -- src/lib/toast-utils.ts | 127 +++----------------- src/types.ts | 19 --- 10 files changed, 32 insertions(+), 414 deletions(-) delete mode 100644 src/components/update-notification.tsx delete mode 100644 src/components/version-selector.tsx diff --git a/package.json b/package.json index 7e19125..cacfd34 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "format:js": "biome check src/ --fix", "format": "pnpm format:js && pnpm format:rust", "cargo": "cd src-tauri && cargo", + "unused-exports:js": "ts-unused-exports tsconfig.json", "check-unused-commands": "cd src-tauri && cargo run --bin check_unused_commands" }, "dependencies": { @@ -71,6 +72,7 @@ "husky": "^9.1.7", "lint-staged": "^16.1.1", "tailwindcss": "^4.1.10", + "ts-unused-exports": "^11.0.1", "tw-animate-css": "^1.3.4", "typescript": "~5.8.3", "typescript-eslint": "^8.34.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3abcf86..834a66e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,6 +147,9 @@ importers: tailwindcss: specifier: ^4.1.10 version: 4.1.10 + ts-unused-exports: + specifier: ^11.0.1 + version: 11.0.1(typescript@5.8.3) tw-animate-css: specifier: ^1.3.4 version: 1.3.4 @@ -3437,6 +3440,12 @@ packages: '@swc/wasm': optional: true + ts-unused-exports@11.0.1: + resolution: {integrity: sha512-b1uIe0B8YfNZjeb+bx62LrB6qaO4CHT8SqMVBkwbwLj7Nh0xQ4J8uV0dS9E6AABId0U4LQ+3yB/HXZBMslGn2A==} + hasBin: true + peerDependencies: + typescript: '>=3.8.3' + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -7022,6 +7031,12 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-unused-exports@11.0.1(typescript@5.8.3): + dependencies: + chalk: 4.1.2 + tsconfig-paths: 3.15.0 + typescript: 5.8.3 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 diff --git a/src-tauri/src/browser_runner.rs b/src-tauri/src/browser_runner.rs index 532234c..69819f6 100644 --- a/src-tauri/src/browser_runner.rs +++ b/src-tauri/src/browser_runner.rs @@ -1465,6 +1465,7 @@ impl BrowserRunner { browser_dir.push(&profile.browser); browser_dir.push(&profile.version); + println!("Browser directory: {browser_dir:?}"); let executable_path = browser .get_executable_path(&browser_dir) .expect("Failed to get executable path"); diff --git a/src/components/update-notification.tsx b/src/components/update-notification.tsx deleted file mode 100644 index 7214f69..0000000 --- a/src/components/update-notification.tsx +++ /dev/null @@ -1,107 +0,0 @@ -"use client"; - -/* eslint-disable @typescript-eslint/no-misused-promises */ - -import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; -import { getBrowserDisplayName } from "@/lib/browser-utils"; -import React from "react"; -import { FaDownload, FaTimes } from "react-icons/fa"; - -interface UpdateNotification { - id: string; - browser: string; - current_version: string; - new_version: string; - affected_profiles: string[]; - is_stable_update: boolean; - timestamp: number; -} - -interface UpdateNotificationProps { - notification: UpdateNotification; - onUpdate: (browser: string, newVersion: string) => Promise; - onDismiss: (notificationId: string) => Promise; - isUpdating?: boolean; -} - -export function UpdateNotificationComponent({ - notification, - onUpdate, - onDismiss, - isUpdating = false, -}: UpdateNotificationProps) { - const browserDisplayName = getBrowserDisplayName(notification.browser); - - const profileText = - notification.affected_profiles.length === 1 - ? `profile "${notification.affected_profiles[0]}"` - : `${notification.affected_profiles.length} profiles`; - - const handleUpdateClick = async () => { - // Dismiss the notification immediately to close the modal - await onDismiss(notification.id); - // Then start the update process - await onUpdate(notification.browser, notification.new_version); - }; - - return ( -
-
-
-
- - {browserDisplayName} Update Available - - - {notification.is_stable_update ? "Stable" : "Nightly"} - -
-
- Update {profileText} from {notification.current_version} to{" "} - {notification.new_version} -
-
- -
- -
- - -
- - {notification.affected_profiles.length > 1 && ( -
- Affected profiles: {notification.affected_profiles.join(", ")} -
- )} -
- ); -} diff --git a/src/components/version-selector.tsx b/src/components/version-selector.tsx deleted file mode 100644 index fec6df4..0000000 --- a/src/components/version-selector.tsx +++ /dev/null @@ -1,156 +0,0 @@ -"use client"; - -import { LoadingButton } from "@/components/loading-button"; -import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, -} from "@/components/ui/command"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; -import { cn } from "@/lib/utils"; -import { useState } from "react"; -import { LuDownload } from "react-icons/lu"; -import { LuCheck, LuChevronsUpDown } from "react-icons/lu"; -import { ScrollArea } from "./ui/scroll-area"; - -interface GithubRelease { - tag_name: string; - assets: { - name: string; - browser_download_url: string; - hash?: string; - }[]; - published_at: string; - is_nightly: boolean; -} - -interface VersionSelectorProps { - selectedVersion: string | null; - onVersionSelect: (version: string | null) => void; - availableVersions: GithubRelease[]; - downloadedVersions: string[]; - isDownloading: boolean; - onDownload: () => void; - placeholder?: string; - showDownloadButton?: boolean; -} - -export function VersionSelector({ - selectedVersion, - onVersionSelect, - availableVersions, - downloadedVersions, - isDownloading, - onDownload, - placeholder = "Select version...", - showDownloadButton = true, -}: VersionSelectorProps) { - const [versionPopoverOpen, setVersionPopoverOpen] = useState(false); - - const isVersionDownloaded = selectedVersion - ? downloadedVersions.includes(selectedVersion) - : false; - - return ( -
- - - - - - - - No versions found. - - [data-radix-scroll-area-viewport]]:max-h-[200px]" - } - > - - {availableVersions.map((version) => { - const isDownloaded = downloadedVersions.includes( - version.tag_name, - ); - return ( - { - onVersionSelect( - currentValue === selectedVersion - ? null - : currentValue, - ); - setVersionPopoverOpen(false); - }} - > - -
- {version.tag_name} - {version.is_nightly && ( - - Nightly - - )} - {isDownloaded && ( - - Downloaded - - )} -
-
- ); - })} -
-
-
-
-
-
- - {/* Download Button */} - {showDownloadButton && selectedVersion && !isVersionDownloaded && ( - { - onDownload(); - }} - variant="outline" - className="w-full" - > - - {isDownloading ? "Downloading..." : "Download Browser"} - - )} -
- ); -} diff --git a/src/hooks/use-browser-support.ts b/src/hooks/use-browser-support.ts index 2f903f6..c035aa6 100644 --- a/src/hooks/use-browser-support.ts +++ b/src/hooks/use-browser-support.ts @@ -1,12 +1,6 @@ import { invoke } from "@tauri-apps/api/core"; import { useEffect, useState } from "react"; -export interface BrowserSupportInfo { - supportedBrowsers: string[]; - isLoading: boolean; - error: string | null; -} - export function useBrowserSupport() { const [supportedBrowsers, setSupportedBrowsers] = useState([]); const [isLoading, setIsLoading] = useState(true); diff --git a/src/hooks/use-permissions.ts b/src/hooks/use-permissions.ts index aa1f9ae..314fa0b 100644 --- a/src/hooks/use-permissions.ts +++ b/src/hooks/use-permissions.ts @@ -20,7 +20,7 @@ const loadMacOSPermissions = async () => { export type PermissionType = "microphone" | "camera"; -export interface UsePermissionsReturn { +interface UsePermissionsReturn { requestPermission: (type: PermissionType) => Promise; isMicrophoneAccessGranted: boolean; isCameraAccessGranted: boolean; diff --git a/src/lib/browser-utils.ts b/src/lib/browser-utils.ts index dd6a81c..ce6e60f 100644 --- a/src/lib/browser-utils.ts +++ b/src/lib/browser-utils.ts @@ -46,14 +46,3 @@ export function getBrowserIcon(browserType: string) { return null; } } - -/** - * Format browser name by capitalizing words and joining with spaces - * (fallback method for simple transformations) - */ -export function formatBrowserName(browserType: string): string { - return browserType - .split("-") - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(" "); -} diff --git a/src/lib/toast-utils.ts b/src/lib/toast-utils.ts index 778a93e..1b03e58 100644 --- a/src/lib/toast-utils.ts +++ b/src/lib/toast-utils.ts @@ -2,27 +2,26 @@ import { UnifiedToast } from "@/components/custom-toast"; import React from "react"; import { toast as sonnerToast } from "sonner"; -// Define toast types locally -export interface BaseToastProps { +interface BaseToastProps { id?: string; title: string; description?: string; duration?: number; } -export interface LoadingToastProps extends BaseToastProps { +interface LoadingToastProps extends BaseToastProps { type: "loading"; } -export interface SuccessToastProps extends BaseToastProps { +interface SuccessToastProps extends BaseToastProps { type: "success"; } -export interface ErrorToastProps extends BaseToastProps { +interface ErrorToastProps extends BaseToastProps { type: "error"; } -export interface DownloadToastProps extends BaseToastProps { +interface DownloadToastProps extends BaseToastProps { type: "download"; stage?: | "downloading" @@ -37,7 +36,7 @@ export interface DownloadToastProps extends BaseToastProps { }; } -export interface VersionUpdateToastProps extends BaseToastProps { +interface VersionUpdateToastProps extends BaseToastProps { type: "version-update"; progress?: { current: number; @@ -47,39 +46,23 @@ export interface VersionUpdateToastProps extends BaseToastProps { }; } -export interface FetchingToastProps extends BaseToastProps { - type: "fetching"; - browserName?: string; -} - -export interface TwilightUpdateToastProps extends BaseToastProps { - type: "twilight-update"; - browserName?: string; - hasUpdate?: boolean; -} - -export type ToastProps = - | LoadingToastProps +type ToastProps = | SuccessToastProps | ErrorToastProps | DownloadToastProps - | VersionUpdateToastProps - | FetchingToastProps - | TwilightUpdateToastProps; + | LoadingToastProps + | VersionUpdateToastProps; -// Unified toast function export function showToast(props: ToastProps & { id?: string }) { const toastId = props.id ?? `toast-${props.type}-${Date.now()}`; - // Improved duration logic - make toasts disappear more quickly let duration: number; if (props.duration !== undefined) { duration = props.duration; } else { switch (props.type) { case "loading": - case "fetching": - duration = 10000; // 10 seconds instead of infinite + duration = 10000; break; case "download": // Only keep infinite for active downloading, others get shorter durations @@ -91,18 +74,15 @@ export function showToast(props: ToastProps & { id?: string }) { duration = 20000; } break; - case "version-update": - duration = 15000; - break; - case "twilight-update": - duration = 10000; - break; case "success": duration = 3000; break; case "error": duration = 10000; break; + case "version-update": + duration = 15000; + break; default: duration = 5000; } @@ -152,22 +132,6 @@ export function showToast(props: ToastProps & { id?: string }) { return toastId; } -// Convenience functions for common use cases -export function showLoadingToast( - title: string, - options?: { - id?: string; - description?: string; - duration?: number; - }, -) { - return showToast({ - type: "loading", - title, - ...options, - }); -} - export function showDownloadToast( browserName: string, version: string, @@ -206,45 +170,6 @@ export function showDownloadToast( }); } -export function showVersionUpdateToast( - title: string, - options?: { - id?: string; - description?: string; - progress?: { - current: number; - total: number; - found: number; - current_browser?: string; - }; - duration?: number; - }, -) { - return showToast({ - type: "version-update", - title, - ...options, - }); -} - -export function showFetchingToast( - browserName: string, - options?: { - id?: string; - description?: string; - duration?: number; - }, -) { - return showToast({ - type: "fetching", - title: `Checking for new ${browserName} versions...`, - description: - options?.description ?? "Fetching latest release information...", - browserName, - ...options, - }); -} - export function showSuccessToast( title: string, options?: { @@ -275,25 +200,6 @@ export function showErrorToast( }); } -export function showTwilightUpdateToast( - browserName: string, - options?: { - id?: string; - description?: string; - hasUpdate?: boolean; - duration?: number; - }, -) { - return showToast({ - type: "twilight-update", - title: options?.hasUpdate - ? `${browserName} twilight update available` - : `Checking for ${browserName} twilight updates...`, - browserName, - ...options, - }); -} - export function showAutoUpdateToast( browserName: string, version: string, @@ -314,17 +220,10 @@ export function showAutoUpdateToast( }); } -// Generic helper for dismissing toasts export function dismissToast(id: string) { sonnerToast.dismiss(id); } -// Dismiss all toasts -export function dismissAllToasts() { - sonnerToast.dismiss(); -} - -// Add a specific function for unified version update progress export function showUnifiedVersionUpdateToast( title: string, options?: { diff --git a/src/types.ts b/src/types.ts index 7cea563..2090176 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,22 +43,3 @@ export interface AppUpdateInfo { is_nightly: boolean; published_at: string; } - -export interface AppVersionInfo { - version: string; - is_nightly: boolean; -} - -export type PermissionType = "microphone" | "camera" | "location"; - -export type PermissionStatus = - | "granted" - | "denied" - | "not_determined" - | "restricted"; - -export interface PermissionInfo { - permission_type: PermissionType; - status: PermissionStatus; - description: string; -}