"use client"; import { invoke } from "@tauri-apps/api/core"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { LoadingButton } from "@/components/loading-button"; import { Badge } from "@/components/ui/badge"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; import { useBrowserState } from "@/hooks/use-browser-state"; import { useProfileEvents } from "@/hooks/use-profile-events"; import { useProxyEvents } from "@/hooks/use-proxy-events"; import { getBrowserDisplayName, getBrowserIcon } from "@/lib/browser-utils"; import type { BrowserProfile } from "@/types"; import { CopyToClipboard } from "./ui/copy-to-clipboard"; import { RippleButton } from "./ui/ripple"; interface ProfileSelectorDialogProps { isOpen: boolean; onClose: () => void; isUpdating: (browser: string) => boolean; url?: string; runningProfiles?: Set; } export function ProfileSelectorDialog({ isOpen, onClose, url, runningProfiles: externalRunningProfiles, isUpdating, }: ProfileSelectorDialogProps) { const { t } = useTranslation(); // Use the centralized profile events hook const { profiles, runningProfiles: hookRunningProfiles } = useProfileEvents(); // Use external runningProfiles if provided, otherwise use hook's runningProfiles const runningProfiles = externalRunningProfiles ?? hookRunningProfiles; const { storedProxies } = useProxyEvents(); const [selectedProfile, setSelectedProfile] = useState(null); const [isLaunching, setIsLaunching] = useState(false); const [launchingProfiles, setLaunchingProfiles] = useState>( new Set(), ); const [stoppingProfiles] = useState>(new Set()); // Use shared browser state hook const browserState = useBrowserState( profiles, runningProfiles, isUpdating, launchingProfiles, stoppingProfiles, ); // Helper function to check if a profile has a proxy const hasProxy = useCallback( (profile: BrowserProfile): boolean => { if (!profile.proxy_id) return false; const proxy = storedProxies.find((p) => p.id === profile.proxy_id); return proxy !== undefined; }, [storedProxies], ); // Helper function to get tooltip content for profiles - now uses shared hook const getProfileTooltipContent = (profile: BrowserProfile): string | null => { return browserState.getProfileTooltipContent(profile); }; const handleOpenUrl = useCallback(async () => { if (!selectedProfile || !url) return; setIsLaunching(true); const selected = profiles.find((p) => p.name === selectedProfile); if (!selected) return; setLaunchingProfiles((prev) => new Set(prev).add(selected.id)); try { await invoke("open_url_with_profile", { profileId: selected.id, url, }); onClose(); } catch (error) { console.error("Failed to open URL with profile:", error); } finally { setIsLaunching(false); if (selected) { setLaunchingProfiles((prev) => { const next = new Set(prev); next.delete(selected.id); return next; }); } } }, [selectedProfile, url, onClose, profiles]); const handleCancel = useCallback(() => { setSelectedProfile(null); onClose(); }, [onClose]); const selectedProfileData = profiles.find((p) => p.name === selectedProfile); // Check if the selected profile can be used for opening links const canOpenWithSelectedProfile = () => { if (!selectedProfileData) return false; return browserState.canUseProfileForLinks(selectedProfileData); }; // Get tooltip content for disabled profiles const getTooltipContent = () => { if (!selectedProfileData) return null; return getProfileTooltipContent(selectedProfileData); }; // Auto-select first available profile when dialog opens and profiles are loaded useEffect(() => { if (isOpen && profiles.length > 0 && !selectedProfile) { // First, try to find a running profile that can be used for opening links const runningAvailableProfile = profiles.find((profile) => { const isRunning = runningProfiles.has(profile.id); // Simple check without browserState dependency return isRunning; }); if (runningAvailableProfile) { setSelectedProfile(runningAvailableProfile.name); } else { // Sort profiles by name and select first const sortedProfiles = [...profiles].sort((a, b) => a.name.localeCompare(b.name), ); setSelectedProfile(sortedProfiles[0].name); } } }, [isOpen, profiles, selectedProfile, runningProfiles]); return ( {t("profileSelector.chooseProfileTitle")}
{url && (
{url}
)}
{profiles.length === 0 ? (
{t("profileSelector.noneAvailableShort")}
{t("profileSelector.noneAvailableLong")}
) : ( )}
{t("common.buttons.cancel")} void handleOpenUrl()} disabled={ !selectedProfile || profiles.length === 0 || !canOpenWithSelectedProfile() } > {t("profileSelector.openButton")} {getTooltipContent() && ( {getTooltipContent()} )}
); }