mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-04-26 22:06:23 +02:00
refactor: better camoufox instance tracking
This commit is contained in:
@@ -20,7 +20,9 @@ export function GroupBadges({
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
<div className="text-sm text-muted-foreground">Loading groups...</div>
|
||||
<div className="flex items-center gap-2 px-4.5 py-1.5 text-xs">
|
||||
Loading groups...
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,9 @@ export function ProfilesDataTable({
|
||||
const [profileToDelete, setProfileToDelete] =
|
||||
React.useState<BrowserProfile | null>(null);
|
||||
const [isDeleting, setIsDeleting] = React.useState(false);
|
||||
const [launchingProfiles, setLaunchingProfiles] = React.useState<Set<string>>(
|
||||
new Set(),
|
||||
);
|
||||
|
||||
const [storedProxies, setStoredProxies] = React.useState<StoredProxy[]>([]);
|
||||
const [selectedProfiles, setSelectedProfiles] = React.useState<Set<string>>(
|
||||
@@ -365,9 +368,41 @@ export function ProfilesDataTable({
|
||||
const profile = row.original;
|
||||
const isRunning =
|
||||
browserState.isClient && runningProfiles.has(profile.name);
|
||||
const isLaunching = launchingProfiles.has(profile.name);
|
||||
const canLaunch = browserState.canLaunchProfile(profile);
|
||||
const tooltipContent = browserState.getLaunchTooltipContent(profile);
|
||||
|
||||
const handleLaunchClick = async () => {
|
||||
if (isRunning) {
|
||||
console.log(
|
||||
`Stopping ${profile.browser} profile: ${profile.name}`,
|
||||
);
|
||||
await onKillProfile(profile);
|
||||
} else {
|
||||
console.log(
|
||||
`Launching ${profile.browser} profile: ${profile.name}`,
|
||||
);
|
||||
setLaunchingProfiles((prev) => new Set(prev).add(profile.name));
|
||||
try {
|
||||
await onLaunchProfile(profile);
|
||||
console.log(
|
||||
`Successfully launched ${profile.browser} profile: ${profile.name}`,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Failed to launch ${profile.browser} profile: ${profile.name}`,
|
||||
error,
|
||||
);
|
||||
} finally {
|
||||
setLaunchingProfiles((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.delete(profile.name);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 items-center">
|
||||
<Tooltip>
|
||||
@@ -376,18 +411,22 @@ export function ProfilesDataTable({
|
||||
<Button
|
||||
variant={isRunning ? "destructive" : "default"}
|
||||
size="sm"
|
||||
disabled={!canLaunch}
|
||||
disabled={!canLaunch || isLaunching}
|
||||
className={cn(
|
||||
"cursor-pointer",
|
||||
"cursor-pointer min-w-[70px]",
|
||||
!canLaunch && "opacity-50",
|
||||
)}
|
||||
onClick={() =>
|
||||
void (isRunning
|
||||
? onKillProfile(profile)
|
||||
: onLaunchProfile(profile))
|
||||
}
|
||||
onClick={() => void handleLaunchClick()}
|
||||
>
|
||||
{isRunning ? "Stop" : "Launch"}
|
||||
{isLaunching ? (
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-3 h-3 border border-current border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
) : isRunning ? (
|
||||
"Stop"
|
||||
) : (
|
||||
"Launch"
|
||||
)}
|
||||
</Button>
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
@@ -408,7 +447,7 @@ export function ProfilesDataTable({
|
||||
onClick={() =>
|
||||
column.toggleSorting(column.getIsSorted() === "asc")
|
||||
}
|
||||
className="h-auto p-0 font-semibold text-left justify-start"
|
||||
className="h-auto p-0 font-semibold text-left justify-start cursor-pointer"
|
||||
>
|
||||
Name
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
@@ -448,7 +487,7 @@ export function ProfilesDataTable({
|
||||
onClick={() =>
|
||||
column.toggleSorting(column.getIsSorted() === "asc")
|
||||
}
|
||||
className="h-auto p-0 font-semibold text-left justify-start"
|
||||
className="h-auto p-0 font-semibold text-left justify-start cursor-pointer"
|
||||
>
|
||||
Browser
|
||||
{column.getIsSorted() === "asc" ? (
|
||||
@@ -677,6 +716,7 @@ export function ProfilesDataTable({
|
||||
onAssignProfilesToGroup,
|
||||
isUpdating,
|
||||
filteredData.length,
|
||||
launchingProfiles.has,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -84,15 +84,22 @@ export function ProfileSelectorDialog({
|
||||
// First, try to find a running profile that can be used for opening links
|
||||
const runningAvailableProfile = profileList.find((profile) => {
|
||||
const isRunning = runningProfiles.has(profile.name);
|
||||
return isRunning && browserState.canUseProfileForLinks(profile);
|
||||
// Simple check without browserState dependency
|
||||
return (
|
||||
isRunning &&
|
||||
profile.browser !== "tor-browser" &&
|
||||
profile.browser !== "mullvad-browser"
|
||||
);
|
||||
});
|
||||
|
||||
if (runningAvailableProfile) {
|
||||
setSelectedProfile(runningAvailableProfile.name);
|
||||
} else {
|
||||
// If no running profile is available, find the first available profile
|
||||
const availableProfile = profileList.find((profile) =>
|
||||
browserState.canUseProfileForLinks(profile),
|
||||
const availableProfile = profileList.find(
|
||||
(profile) =>
|
||||
profile.browser !== "tor-browser" &&
|
||||
profile.browser !== "mullvad-browser",
|
||||
);
|
||||
if (availableProfile) {
|
||||
setSelectedProfile(availableProfile.name);
|
||||
@@ -104,7 +111,7 @@ export function ProfileSelectorDialog({
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [runningProfiles, browserState]);
|
||||
}, [runningProfiles]);
|
||||
|
||||
// Helper function to get tooltip content for profiles - now uses shared hook
|
||||
const getProfileTooltipContent = (profile: BrowserProfile): string | null => {
|
||||
@@ -227,11 +234,12 @@ export function ProfileSelectorDialog({
|
||||
return (
|
||||
<Tooltip key={profile.name}>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="inline-flex">
|
||||
<SelectItem
|
||||
value={profile.name}
|
||||
disabled={!canUseForLinks}
|
||||
>
|
||||
<SelectItem
|
||||
value={profile.name}
|
||||
disabled={!canUseForLinks}
|
||||
asChild
|
||||
>
|
||||
<span>
|
||||
<div
|
||||
className={`flex items-center gap-2 ${
|
||||
!canUseForLinks ? "opacity-50" : ""
|
||||
@@ -276,8 +284,8 @@ export function ProfileSelectorDialog({
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</SelectItem>
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
</TooltipTrigger>
|
||||
{tooltipContent && (
|
||||
<TooltipContent>{tooltipContent}</TooltipContent>
|
||||
|
||||
Reference in New Issue
Block a user