feat: ephemeral profiles

This commit is contained in:
zhom
2026-02-22 10:17:25 +04:00
parent 2e193987df
commit 3732d3a6e1
21 changed files with 354 additions and 33 deletions
+28
View File
@@ -8,6 +8,7 @@ import { LoadingButton } from "@/components/loading-button";
import { ProxyFormDialog } from "@/components/proxy-form-dialog";
import { SharedCamoufoxConfigForm } from "@/components/shared-camoufox-config-form";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
Dialog,
DialogContent,
@@ -75,6 +76,7 @@ interface CreateProfileDialogProps {
camoufoxConfig?: CamoufoxConfig;
wayfernConfig?: WayfernConfig;
groupId?: string;
ephemeral?: boolean;
}) => Promise<void>;
selectedGroupId?: string;
crossOsUnlocked?: boolean;
@@ -164,6 +166,7 @@ export function CreateProfileDialog({
const { vpnConfigs } = useVpnEvents();
const [showProxyForm, setShowProxyForm] = useState(false);
const [isCreating, setIsCreating] = useState(false);
const [ephemeral, setEphemeral] = useState(false);
const [releaseTypes, setReleaseTypes] = useState<BrowserReleaseTypes>();
const [isLoadingReleaseTypes, setIsLoadingReleaseTypes] = useState(false);
const [releaseTypesError, setReleaseTypesError] = useState<string | null>(
@@ -382,6 +385,7 @@ export function CreateProfileDialog({
wayfernConfig: finalWayfernConfig,
groupId:
selectedGroupId !== "default" ? selectedGroupId : undefined,
ephemeral,
});
} else {
// Default to Camoufox
@@ -405,6 +409,7 @@ export function CreateProfileDialog({
camoufoxConfig: finalCamoufoxConfig,
groupId:
selectedGroupId !== "default" ? selectedGroupId : undefined,
ephemeral,
});
}
} else {
@@ -459,6 +464,7 @@ export function CreateProfileDialog({
setWayfernConfig({
os: getCurrentOS() as WayfernOS, // Reset to current OS
});
setEphemeral(false);
onClose();
};
@@ -660,6 +666,28 @@ export function CreateProfileDialog({
/>
</div>
{/* Ephemeral Toggle */}
<div className="flex items-center gap-2">
<Checkbox
id="ephemeral"
checked={ephemeral}
onCheckedChange={(checked) =>
setEphemeral(checked === true)
}
/>
<div className="flex flex-col">
<Label
htmlFor="ephemeral"
className="cursor-pointer"
>
Ephemeral
</Label>
<span className="text-xs text-muted-foreground">
Browser data is deleted when closed
</span>
</div>
</div>
{selectedBrowser === "wayfern" ? (
// Wayfern Configuration
<div className="space-y-6">
+21 -9
View File
@@ -1940,7 +1940,14 @@ export function ProfilesDataTable({
}
}}
>
{display}
<span className="flex items-center gap-1">
{display}
{profile.ephemeral && (
<span className="px-1 py-0.5 text-[10px] leading-none rounded bg-muted text-muted-foreground font-medium">
Ephemeral
</span>
)}
</span>
</button>
);
},
@@ -2397,6 +2404,7 @@ export function ProfilesDataTable({
)}
{(profile.browser === "camoufox" ||
profile.browser === "wayfern") &&
!profile.ephemeral &&
meta.onCopyCookiesToProfile && (
<DropdownMenuItem
onClick={() => {
@@ -2414,6 +2422,7 @@ export function ProfilesDataTable({
)}
{(profile.browser === "camoufox" ||
profile.browser === "wayfern") &&
!profile.ephemeral &&
meta.onImportCookies && (
<DropdownMenuItem
onClick={() => {
@@ -2431,6 +2440,7 @@ export function ProfilesDataTable({
)}
{(profile.browser === "camoufox" ||
profile.browser === "wayfern") &&
!profile.ephemeral &&
meta.onExportCookies && (
<DropdownMenuItem
onClick={() => {
@@ -2446,14 +2456,16 @@ export function ProfilesDataTable({
</span>
</DropdownMenuItem>
)}
<DropdownMenuItem
onClick={() => {
meta.onCloneProfile?.(profile);
}}
disabled={isDisabled}
>
Clone Profile
</DropdownMenuItem>
{!profile.ephemeral && (
<DropdownMenuItem
onClick={() => {
meta.onCloneProfile?.(profile);
}}
disabled={isDisabled}
>
Clone Profile
</DropdownMenuItem>
)}
<DropdownMenuItem
onClick={() => {
setProfileToDelete(profile);