refactor: block selection if the profile is launching or stopping

This commit is contained in:
zhom
2025-08-04 07:02:38 +04:00
parent e675441171
commit 83f4c2c162
3 changed files with 150 additions and 18 deletions
+58 -10
View File
@@ -106,6 +106,9 @@ export function ProfilesDataTable({
const [launchingProfiles, setLaunchingProfiles] = React.useState<Set<string>>(
new Set(),
);
const [stoppingProfiles, setStoppingProfiles] = React.useState<Set<string>>(
new Set(),
);
const [storedProxies, setStoredProxies] = React.useState<StoredProxy[]>([]);
const [selectedProfiles, setSelectedProfiles] = React.useState<Set<string>>(
@@ -156,6 +159,8 @@ export function ProfilesDataTable({
filteredData,
runningProfiles,
isUpdating,
launchingProfiles,
stoppingProfiles,
);
// Load stored proxies
@@ -174,7 +179,7 @@ export function ProfilesDataTable({
}
}, [browserState.isClient, loadStoredProxies]);
// Automatically deselect profiles that become running or updating
// Automatically deselect profiles that become running, updating, launching, or stopping
React.useEffect(() => {
setSelectedProfiles((prev) => {
const newSet = new Set(prev);
@@ -185,9 +190,11 @@ export function ProfilesDataTable({
if (profile) {
const isRunning =
browserState.isClient && runningProfiles.has(profile.name);
const isLaunching = launchingProfiles.has(profile.name);
const isStopping = stoppingProfiles.has(profile.name);
const isBrowserUpdating = isUpdating(profile.browser);
if (isRunning || isBrowserUpdating) {
if (isRunning || isLaunching || isStopping || isBrowserUpdating) {
newSet.delete(profileName);
hasChanges = true;
}
@@ -204,6 +211,8 @@ export function ProfilesDataTable({
}, [
filteredData,
runningProfiles,
launchingProfiles,
stoppingProfiles,
isUpdating,
browserState.isClient,
onSelectedProfilesChange,
@@ -336,8 +345,15 @@ export function ProfilesDataTable({
.filter((profile) => {
const isRunning =
browserState.isClient && runningProfiles.has(profile.name);
const isLaunching = launchingProfiles.has(profile.name);
const isStopping = stoppingProfiles.has(profile.name);
const isBrowserUpdating = isUpdating(profile.browser);
return !isRunning && !isBrowserUpdating;
return (
!isRunning &&
!isLaunching &&
!isStopping &&
!isBrowserUpdating
);
})
.map((profile) => profile.name),
)
@@ -356,6 +372,8 @@ export function ProfilesDataTable({
onSelectedProfilesChange,
browserState.isClient,
runningProfiles,
launchingProfiles,
stoppingProfiles,
isUpdating,
],
);
@@ -368,8 +386,12 @@ export function ProfilesDataTable({
const selectableProfiles = filteredData.filter((profile) => {
const isRunning =
browserState.isClient && runningProfiles.has(profile.name);
const isLaunching = launchingProfiles.has(profile.name);
const isStopping = stoppingProfiles.has(profile.name);
const isBrowserUpdating = isUpdating(profile.browser);
return !isRunning && !isBrowserUpdating;
return (
!isRunning && !isLaunching && !isStopping && !isBrowserUpdating
);
});
return (
@@ -393,14 +415,21 @@ export function ProfilesDataTable({
const isSelected = selectedProfiles.has(profile.name);
const isRunning =
browserState.isClient && runningProfiles.has(profile.name);
const isLaunching = launchingProfiles.has(profile.name);
const isStopping = stoppingProfiles.has(profile.name);
const isBrowserUpdating = isUpdating(browser);
const isDisabled = isRunning || isBrowserUpdating;
const isDisabled =
isRunning || isLaunching || isStopping || isBrowserUpdating;
// Show tooltip for disabled profiles
if (isDisabled) {
const tooltipMessage = isRunning
? "Can't modify running profile"
: "Can't modify profile while browser is updating";
: isLaunching
? "Can't modify profile while launching"
: isStopping
? "Can't modify profile while stopping"
: "Can't modify profile while browser is updating";
return (
<Tooltip>
@@ -462,6 +491,7 @@ export function ProfilesDataTable({
const isRunning =
browserState.isClient && runningProfiles.has(profile.name);
const isLaunching = launchingProfiles.has(profile.name);
const isStopping = stoppingProfiles.has(profile.name);
const canLaunch = browserState.canLaunchProfile(profile);
const tooltipContent = browserState.getLaunchTooltipContent(profile);
@@ -470,7 +500,24 @@ export function ProfilesDataTable({
console.log(
`Stopping ${profile.browser} profile: ${profile.name}`,
);
await onKillProfile(profile);
setStoppingProfiles((prev) => new Set(prev).add(profile.name));
try {
await onKillProfile(profile);
console.log(
`Successfully stopped ${profile.browser} profile: ${profile.name}`,
);
} catch (error) {
console.error(
`Failed to stop ${profile.browser} profile: ${profile.name}`,
error,
);
} finally {
setStoppingProfiles((prev) => {
const next = new Set(prev);
next.delete(profile.name);
return next;
});
}
} else {
console.log(
`Launching ${profile.browser} profile: ${profile.name}`,
@@ -504,14 +551,14 @@ export function ProfilesDataTable({
<Button
variant={isRunning ? "destructive" : "default"}
size="sm"
disabled={!canLaunch || isLaunching}
disabled={!canLaunch || isLaunching || isStopping}
className={cn(
"cursor-pointer min-w-[70px]",
!canLaunch && "opacity-50",
)}
onClick={() => void handleLaunchClick()}
>
{isLaunching ? (
{isLaunching || isStopping ? (
<div className="flex gap-1 items-center">
<div className="w-3 h-3 rounded-full border border-current animate-spin border-t-transparent" />
</div>
@@ -808,7 +855,8 @@ export function ProfilesDataTable({
onChangeVersion,
onAssignProfilesToGroup,
isUpdating,
launchingProfiles.has,
launchingProfiles,
stoppingProfiles,
filteredData,
browserState.isClient,
],
+31 -1
View File
@@ -51,9 +51,21 @@ export function ProfileSelectorDialog({
const [isLoading, setIsLoading] = useState(false);
const [isLaunching, setIsLaunching] = useState(false);
const [storedProxies, setStoredProxies] = useState<StoredProxy[]>([]);
const [launchingProfiles, setLaunchingProfiles] = useState<Set<string>>(
new Set(),
);
const [stoppingProfiles, _setStoppingProfiles] = useState<Set<string>>(
new Set(),
);
// Use shared browser state hook
const browserState = useBrowserState(profiles, runningProfiles, isUpdating);
const browserState = useBrowserState(
profiles,
runningProfiles,
isUpdating,
launchingProfiles,
stoppingProfiles,
);
// Helper function to check if a profile has a proxy
const hasProxy = useCallback(
@@ -116,6 +128,7 @@ export function ProfileSelectorDialog({
if (!selectedProfile || !url) return;
setIsLaunching(true);
setLaunchingProfiles((prev) => new Set(prev).add(selectedProfile));
try {
await invoke("open_url_with_profile", {
profileName: selectedProfile,
@@ -126,6 +139,11 @@ export function ProfileSelectorDialog({
console.error("Failed to open URL with profile:", error);
} finally {
setIsLaunching(false);
setLaunchingProfiles((prev) => {
const next = new Set(prev);
next.delete(selectedProfile);
return next;
});
}
}, [selectedProfile, url, onClose]);
@@ -221,6 +239,8 @@ export function ProfileSelectorDialog({
<SelectContent>
{profiles.map((profile) => {
const isRunning = runningProfiles.has(profile.name);
const isLaunching = launchingProfiles.has(profile.name);
const isStopping = stoppingProfiles.has(profile.name);
const canUseForLinks =
browserState.canUseProfileForLinks(profile);
const tooltipContent = getProfileTooltipContent(profile);
@@ -269,6 +289,16 @@ export function ProfileSelectorDialog({
Running
</Badge>
)}
{isLaunching && (
<Badge variant="outline" className="text-xs">
Launching
</Badge>
)}
{isStopping && (
<Badge variant="outline" className="text-xs">
Stopping
</Badge>
)}
{!canUseForLinks && (
<Badge
variant="destructive"