refactor: cleanup

This commit is contained in:
zhom
2026-05-29 06:31:42 +04:00
parent 17e33aa53f
commit ecafb5e1c0
40 changed files with 484 additions and 2344 deletions
+6 -37
View File
@@ -23,7 +23,6 @@ import { GroupManagementDialog } from "@/components/group-management-dialog";
import HomeHeader from "@/components/home-header";
import { ImportProfileDialog } from "@/components/import-profile-dialog";
import { IntegrationsDialog } from "@/components/integrations-dialog";
import { LaunchOnLoginDialog } from "@/components/launch-on-login-dialog";
import { PermissionDialog } from "@/components/permission-dialog";
import { ProfilesDataTable } from "@/components/profile-data-table";
import {
@@ -215,8 +214,6 @@ export default function Home() {
const [passwordDialogMode, setPasswordDialogMode] =
useState<PasswordDialogMode>("set");
const pendingLaunchAfterUnlockRef = useRef<BrowserProfile | null>(null);
const [hasCheckedStartupPrompt, setHasCheckedStartupPrompt] = useState(false);
const [launchOnLoginDialogOpen, setLaunchOnLoginDialogOpen] = useState(false);
const [windowResizeWarningOpen, setWindowResizeWarningOpen] = useState(false);
const [windowResizeWarningBrowserType, setWindowResizeWarningBrowserType] =
useState<string | undefined>(undefined);
@@ -546,24 +543,6 @@ export default function Home() {
}
}, [handleUrlOpen, hasCheckedStartupUrl]);
const checkStartupPrompt = useCallback(async () => {
// Only check once during app startup to prevent reopening after dismissing notifications
if (hasCheckedStartupPrompt) return;
try {
const shouldShow = await invoke<boolean>(
"should_show_launch_on_login_prompt",
);
if (shouldShow) {
setLaunchOnLoginDialogOpen(true);
}
} catch (error) {
console.error("Failed to check startup prompt:", error);
} finally {
setHasCheckedStartupPrompt(true);
}
}, [hasCheckedStartupPrompt]);
// Handle profile errors from useProfileEvents hook
useEffect(() => {
if (profilesError) {
@@ -1190,9 +1169,6 @@ export default function Home() {
}, [profiles, t]);
useEffect(() => {
// Check for startup default browser prompt
void checkStartupPrompt();
// Listen for URL open events and get cleanup function
const setupListeners = async () => {
const cleanup = await listenForUrlEvents();
@@ -1235,7 +1211,6 @@ export default function Home() {
};
}, [
checkForUpdates,
checkStartupPrompt,
listenForUrlEvents,
checkCurrentUrl,
checkMissingBinaries,
@@ -1337,11 +1312,13 @@ export default function Home() {
showToast({
id: "browser-support-ending-warning",
type: "error",
title: "Browser support ending soon",
description: `Support for the following profiles will be removed on March 15, 2026: ${unsupportedNames}. Please migrate to Wayfern or Camoufox profiles.`,
title: t("browserSupport.endingSoonTitle"),
description: t("browserSupport.endingSoonDescription", {
profiles: unsupportedNames,
}),
duration: 15000,
action: {
label: "Learn more",
label: t("common.buttons.learnMore"),
onClick: () => {
const event = new CustomEvent("url-open-request", {
detail: "https://github.com/zhom/donutbrowser/discussions",
@@ -1351,7 +1328,7 @@ export default function Home() {
},
});
}
}, [profiles]);
}, [profiles, t]);
// Re-check Wayfern terms when a browser download completes
useEffect(() => {
@@ -1851,14 +1828,6 @@ export default function Home() {
onClose={checkTrialStatus}
/>
{/* Launch on Login Dialog - shown on every startup until enabled or declined */}
<LaunchOnLoginDialog
isOpen={launchOnLoginDialogOpen}
onClose={() => {
setLaunchOnLoginDialogOpen(false);
}}
/>
<WindowResizeWarningDialog
isOpen={windowResizeWarningOpen}
browserType={windowResizeWarningBrowserType}
+19 -1
View File
@@ -15,7 +15,7 @@ import {
import { RippleButton } from "./ui/ripple";
export function CloseConfirmDialog() {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
@@ -29,6 +29,24 @@ export function CloseConfirmDialog() {
};
}, []);
// The native tray menu is built in Rust and cannot read the active language,
// so push localized labels to it on mount and whenever the language changes.
useEffect(() => {
const syncTrayMenu = () => {
void invoke("update_tray_menu", {
showLabel: t("tray.show"),
quitLabel: t("tray.quit"),
}).catch(() => {
// Tray is desktop-only; ignore on platforms without one.
});
};
syncTrayMenu();
i18n.on("languageChanged", syncTrayMenu);
return () => {
i18n.off("languageChanged", syncTrayMenu);
};
}, [t, i18n]);
const handleMinimize = async () => {
setIsOpen(false);
try {
-106
View File
@@ -1,106 +0,0 @@
"use client";
import { invoke } from "@tauri-apps/api/core";
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { LoadingButton } from "@/components/loading-button";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { showErrorToast, showSuccessToast } from "@/lib/toast-utils";
interface LaunchOnLoginDialogProps {
isOpen: boolean;
onClose: () => void;
}
export function LaunchOnLoginDialog({
isOpen,
onClose,
}: LaunchOnLoginDialogProps) {
const { t } = useTranslation();
const [isEnabling, setIsEnabling] = useState(false);
const [isDeclining, setIsDeclining] = useState(false);
const handleEnable = useCallback(async () => {
setIsEnabling(true);
try {
await invoke("enable_launch_on_login");
showSuccessToast(t("launchOnLogin.enableSuccess"));
onClose();
} catch (error) {
console.error("Failed to enable launch on login:", error);
showErrorToast(t("launchOnLogin.enableFailed"), {
description:
error instanceof Error ? error.message : t("launchOnLogin.tryAgain"),
});
} finally {
setIsEnabling(false);
}
}, [onClose, t]);
const handleDecline = useCallback(async () => {
setIsDeclining(true);
try {
await invoke("decline_launch_on_login");
onClose();
} catch (error) {
console.error("Failed to decline launch on login:", error);
showErrorToast(t("launchOnLogin.declineFailed"), {
description:
error instanceof Error ? error.message : t("launchOnLogin.tryAgain"),
});
} finally {
setIsDeclining(false);
}
}, [onClose, t]);
return (
<Dialog open={isOpen}>
<DialogContent
className="sm:max-w-sm"
onEscapeKeyDown={(e) => {
e.preventDefault();
}}
onPointerDownOutside={(e) => {
e.preventDefault();
}}
onInteractOutside={(e) => {
e.preventDefault();
}}
>
<DialogHeader>
<DialogTitle>{t("launchOnLogin.title")}</DialogTitle>
</DialogHeader>
<p className="text-sm text-muted-foreground">
{t("launchOnLogin.description")}
</p>
<DialogFooter className="flex-row justify-between sm:justify-between">
<Button
variant="ghost"
onClick={handleDecline}
disabled={isEnabling || isDeclining}
>
{isDeclining
? t("launchOnLogin.declining")
: t("launchOnLogin.declineButton")}
</Button>
<LoadingButton
onClick={handleEnable}
isLoading={isEnabling}
disabled={isDeclining}
>
{t("launchOnLogin.enableButton")}
</LoadingButton>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
+81 -31
View File
@@ -422,7 +422,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="Mozilla/5.0..."
placeholder={t("common.placeholders.example", {
value: "Mozilla/5.0...",
})}
/>
</div>
<div className="space-y-2">
@@ -436,7 +438,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., MacIntel, Win32"
placeholder={t("common.placeholders.example", {
value: "MacIntel, Win32",
})}
/>
</div>
<div className="space-y-2">
@@ -452,7 +456,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., 5.0 (Macintosh)"
placeholder={t("common.placeholders.example", {
value: "5.0 (Macintosh)",
})}
/>
</div>
<div className="space-y-2">
@@ -487,7 +493,7 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 8"
placeholder={t("common.placeholders.example", { value: "8" })}
/>
</div>
<div className="space-y-2">
@@ -504,7 +510,7 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
<div className="space-y-2">
@@ -549,7 +555,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., en-US"
placeholder={t("common.placeholders.example", {
value: "en-US",
})}
/>
</div>
</div>
@@ -573,7 +581,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -590,7 +600,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1080"
placeholder={t("common.placeholders.example", {
value: "1080",
})}
/>
</div>
<div className="space-y-2">
@@ -607,7 +619,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -624,7 +638,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1055"
placeholder={t("common.placeholders.example", {
value: "1055",
})}
/>
</div>
<div className="space-y-2">
@@ -641,7 +657,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 30"
placeholder={t("common.placeholders.example", {
value: "30",
})}
/>
</div>
<div className="space-y-2">
@@ -658,7 +676,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 30"
placeholder={t("common.placeholders.example", {
value: "30",
})}
/>
</div>
</div>
@@ -682,7 +702,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1512"
placeholder={t("common.placeholders.example", {
value: "1512",
})}
/>
</div>
<div className="space-y-2">
@@ -699,7 +721,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 886"
placeholder={t("common.placeholders.example", {
value: "886",
})}
/>
</div>
<div className="space-y-2">
@@ -716,7 +740,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1512"
placeholder={t("common.placeholders.example", {
value: "1512",
})}
/>
</div>
<div className="space-y-2">
@@ -733,7 +759,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 886"
placeholder={t("common.placeholders.example", {
value: "886",
})}
/>
</div>
<div className="space-y-2">
@@ -748,7 +776,7 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
<div className="space-y-2">
@@ -763,7 +791,7 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
</div>
@@ -786,7 +814,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 41.0019"
placeholder={t("common.placeholders.example", {
value: "41.0019",
})}
/>
</div>
<div className="space-y-2">
@@ -802,7 +832,9 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 28.9645"
placeholder={t("common.placeholders.example", {
value: "28.9645",
})}
/>
</div>
<div className="space-y-2">
@@ -817,7 +849,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., America/New_York"
placeholder={t("common.placeholders.example", {
value: "America/New_York",
})}
/>
</div>
</div>
@@ -840,7 +874,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., tr"
placeholder={t("common.placeholders.example", {
value: "tr",
})}
/>
</div>
<div className="space-y-2">
@@ -854,7 +890,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., TR"
placeholder={t("common.placeholders.example", {
value: "TR",
})}
/>
</div>
<div className="space-y-2">
@@ -868,7 +906,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., Latn"
placeholder={t("common.placeholders.example", {
value: "Latn",
})}
/>
</div>
</div>
@@ -891,7 +931,9 @@ export function SharedCamoufoxConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., Mesa"
placeholder={t("common.placeholders.example", {
value: "Mesa",
})}
/>
</div>
<div className="space-y-2">
@@ -1053,7 +1095,7 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
<div className="space-y-2">
@@ -1071,7 +1113,7 @@ export function SharedCamoufoxConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
</div>
@@ -1240,7 +1282,9 @@ export function SharedCamoufoxConfigForm({
: undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -1259,7 +1303,9 @@ export function SharedCamoufoxConfigForm({
: undefined,
);
}}
placeholder="e.g., 1080"
placeholder={t("common.placeholders.example", {
value: "1080",
})}
/>
</div>
<div className="space-y-2">
@@ -1278,7 +1324,9 @@ export function SharedCamoufoxConfigForm({
: undefined,
);
}}
placeholder="e.g., 800"
placeholder={t("common.placeholders.example", {
value: "800",
})}
/>
</div>
<div className="space-y-2">
@@ -1297,7 +1345,9 @@ export function SharedCamoufoxConfigForm({
: undefined,
);
}}
placeholder="e.g., 600"
placeholder={t("common.placeholders.example", {
value: "600",
})}
/>
</div>
</div>
+90 -34
View File
@@ -302,7 +302,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="Mozilla/5.0..."
placeholder={t("common.placeholders.example", {
value: "Mozilla/5.0...",
})}
/>
</div>
<div className="space-y-2">
@@ -334,7 +336,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., 10.0.0"
placeholder={t("common.placeholders.example", {
value: "10.0.0",
})}
/>
</div>
<div className="space-y-2">
@@ -348,7 +352,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., Google Chrome"
placeholder={t("common.placeholders.example", {
value: "Google Chrome",
})}
/>
</div>
<div className="space-y-2">
@@ -364,7 +370,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., 143"
placeholder={t("common.placeholders.example", {
value: "143",
})}
/>
</div>
</div>
@@ -388,7 +396,7 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 8"
placeholder={t("common.placeholders.example", { value: "8" })}
/>
</div>
<div className="space-y-2">
@@ -405,7 +413,7 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
<div className="space-y-2">
@@ -422,7 +430,7 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 8"
placeholder={t("common.placeholders.example", { value: "8" })}
/>
</div>
</div>
@@ -446,7 +454,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -463,7 +473,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1080"
placeholder={t("common.placeholders.example", {
value: "1080",
})}
/>
</div>
<div className="space-y-2">
@@ -481,7 +493,9 @@ export function WayfernConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 1.0"
placeholder={t("common.placeholders.example", {
value: "1.0",
})}
/>
</div>
<div className="space-y-2">
@@ -498,7 +512,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -515,7 +531,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1040"
placeholder={t("common.placeholders.example", {
value: "1040",
})}
/>
</div>
<div className="space-y-2">
@@ -532,7 +550,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 24"
placeholder={t("common.placeholders.example", {
value: "24",
})}
/>
</div>
</div>
@@ -556,7 +576,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -573,7 +595,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1040"
placeholder={t("common.placeholders.example", {
value: "1040",
})}
/>
</div>
<div className="space-y-2">
@@ -590,7 +614,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -607,7 +633,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 940"
placeholder={t("common.placeholders.example", {
value: "940",
})}
/>
</div>
<div className="space-y-2">
@@ -622,7 +650,7 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
<div className="space-y-2">
@@ -637,7 +665,7 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 0"
placeholder={t("common.placeholders.example", { value: "0" })}
/>
</div>
</div>
@@ -660,7 +688,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., en-US"
placeholder={t("common.placeholders.example", {
value: "en-US",
})}
/>
</div>
<div className="space-y-2">
@@ -740,7 +770,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., America/New_York"
placeholder={t("common.placeholders.example", {
value: "America/New_York",
})}
/>
</div>
<div className="space-y-2">
@@ -775,7 +807,9 @@ export function WayfernConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 40.7128"
placeholder={t("common.placeholders.example", {
value: "40.7128",
})}
/>
</div>
<div className="space-y-2">
@@ -791,7 +825,9 @@ export function WayfernConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., -74.0060"
placeholder={t("common.placeholders.example", {
value: "-74.0060",
})}
/>
</div>
<div className="space-y-2">
@@ -806,7 +842,9 @@ export function WayfernConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 100"
placeholder={t("common.placeholders.example", {
value: "100",
})}
/>
</div>
</div>
@@ -829,7 +867,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., Intel"
placeholder={t("common.placeholders.example", {
value: "Intel",
})}
/>
</div>
<div className="space-y-2">
@@ -926,7 +966,9 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 48000"
placeholder={t("common.placeholders.example", {
value: "48000",
})}
/>
</div>
<div className="space-y-2">
@@ -943,7 +985,7 @@ export function WayfernConfigForm({
e.target.value ? parseInt(e.target.value, 10) : undefined,
);
}}
placeholder="e.g., 2"
placeholder={t("common.placeholders.example", { value: "2" })}
/>
</div>
</div>
@@ -987,7 +1029,9 @@ export function WayfernConfigForm({
e.target.value ? parseFloat(e.target.value) : undefined,
);
}}
placeholder="e.g., 0.85"
placeholder={t("common.placeholders.example", {
value: "0.85",
})}
/>
</div>
</div>
@@ -1008,7 +1052,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., Google Inc."
placeholder={t("common.placeholders.example", {
value: "Google Inc.",
})}
/>
</div>
<div className="space-y-2">
@@ -1038,7 +1084,9 @@ export function WayfernConfigForm({
e.target.value || undefined,
);
}}
placeholder="e.g., 20030107"
placeholder={t("common.placeholders.example", {
value: "20030107",
})}
/>
</div>
</div>
@@ -1197,7 +1245,9 @@ export function WayfernConfigForm({
: undefined,
);
}}
placeholder="e.g., 1920"
placeholder={t("common.placeholders.example", {
value: "1920",
})}
/>
</div>
<div className="space-y-2">
@@ -1216,7 +1266,9 @@ export function WayfernConfigForm({
: undefined,
);
}}
placeholder="e.g., 1080"
placeholder={t("common.placeholders.example", {
value: "1080",
})}
/>
</div>
<div className="space-y-2">
@@ -1235,7 +1287,9 @@ export function WayfernConfigForm({
: undefined,
);
}}
placeholder="e.g., 800"
placeholder={t("common.placeholders.example", {
value: "800",
})}
/>
</div>
<div className="space-y-2">
@@ -1254,7 +1308,9 @@ export function WayfernConfigForm({
: undefined,
);
}}
placeholder="e.g., 600"
placeholder={t("common.placeholders.example", {
value: "600",
})}
/>
</div>
</div>
+1 -1
View File
@@ -71,7 +71,7 @@ export function useAppUpdateNotifications() {
percentage: 0,
speed: undefined,
eta: undefined,
message: "Starting update...",
message: t("appUpdate.toast.startingUpdate"),
});
await invoke("download_and_prepare_app_update", {
+2 -2
View File
@@ -443,7 +443,7 @@ export function useBrowserDownload() {
showToast({
id: "geoip-download",
type: "download",
title: "Downloading GeoIP database",
title: i18n.t("browserDownload.toast.geoipDownloading"),
stage: "downloading",
progress: {
percentage,
@@ -455,7 +455,7 @@ export function useBrowserDownload() {
showToast({
id: "geoip-download",
type: "download",
title: "GeoIP database downloaded successfully!",
title: i18n.t("browserDownload.toast.geoipDownloaded"),
stage: "completed",
});
}
+35 -13
View File
@@ -62,8 +62,12 @@ export function useUpdateNotifications(
showToast({
id: `auto-update-started-${browser}-${newVersion}`,
type: "loading",
title: `${browserDisplayName} update started`,
description: `Version ${newVersion} download will begin shortly. Browser launch is disabled until update completes.`,
title: i18n.t("versionUpdater.toast.updateStarted", {
browser: browserDisplayName,
}),
description: i18n.t("versionUpdater.toast.updateStartedDescription", {
version: newVersion,
}),
duration: 4000,
});
@@ -83,8 +87,11 @@ export function useUpdateNotifications(
showToast({
id: `auto-update-skip-download-${browser}-${newVersion}`,
type: "success",
title: `${browserDisplayName} ${newVersion} already available`,
description: "Updating profile configurations...",
title: i18n.t("versionUpdater.toast.alreadyAvailable", {
browser: browserDisplayName,
version: newVersion,
}),
description: i18n.t("versionUpdater.toast.updatingProfiles"),
duration: 3000,
});
} else {
@@ -92,8 +99,11 @@ export function useUpdateNotifications(
showToast({
id: `auto-update-download-starting-${browser}-${newVersion}`,
type: "loading",
title: `Starting ${browserDisplayName} ${newVersion} download`,
description: "Download progress will be shown below...",
title: i18n.t("versionUpdater.toast.downloadStarting", {
browser: browserDisplayName,
version: newVersion,
}),
description: i18n.t("versionUpdater.toast.downloadProgressBelow"),
duration: 4000,
});
@@ -115,24 +125,36 @@ export function useUpdateNotifications(
// Show success message based on whether profiles were updated
if (updatedProfiles.length > 0) {
const profileText =
const description =
updatedProfiles.length === 1
? `Profile "${updatedProfiles[0]}" has been updated`
: `${updatedProfiles.length} profiles have been updated`;
? i18n.t("versionUpdater.toast.singleProfileUpdated", {
name: updatedProfiles[0],
version: newVersion,
})
: i18n.t("versionUpdater.toast.multipleProfilesUpdated", {
count: updatedProfiles.length,
version: newVersion,
});
showToast({
id: `auto-update-success-${browser}-${newVersion}`,
type: "success",
title: `${browserDisplayName} update completed`,
description: `${profileText} to version ${newVersion}. You can now launch your browsers with the latest version.`,
title: i18n.t("versionUpdater.toast.updateCompleted", {
browser: browserDisplayName,
}),
description,
duration: 6000,
});
} else {
showToast({
id: `auto-update-success-${browser}-${newVersion}`,
type: "success",
title: `${browserDisplayName} update completed`,
description: `Version ${newVersion} is now available. Running profiles will use the new version when restarted.`,
title: i18n.t("versionUpdater.toast.updateCompleted", {
browser: browserDisplayName,
}),
description: i18n.t("versionUpdater.toast.versionAvailable", {
version: newVersion,
}),
duration: 6000,
});
}
+7 -1
View File
@@ -139,7 +139,13 @@ export function useVersionUpdater() {
try {
// Show auto-update start notification
showAutoUpdateToast(browserDisplayName, new_version, {
description: `Downloading ${browserDisplayName} ${new_version} automatically. Progress will be shown below.`,
description: i18n.t(
"versionUpdater.toast.autoDownloadStarted",
{
browser: browserDisplayName,
version: new_version,
},
),
});
// Dismiss the update notification in the backend
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "Minimize",
"saving": "Saving…",
"saved": "Saved",
"copied": "Copied"
"copied": "Copied",
"learnMore": "Learn more"
},
"status": {
"active": "Active",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "Copy",
"copied": "Copied"
},
"placeholders": {
"example": "e.g., {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "Creating...",
"createButton": "Create"
},
"launchOnLogin": {
"title": "Enable Launch on Login?",
"description": "Running in the background helps keep your proxies and browsers alive.",
"declineButton": "Don't Ask Again",
"declining": "...",
"enableButton": "Enable",
"enableSuccess": "Launch on login enabled",
"enableFailed": "Failed to enable launch on login",
"declineFailed": "Failed to save preference",
"tryAgain": "Please try again"
},
"wayfernTerms": {
"title": "Wayfern Terms and Conditions",
"description": "Before using Donut Browser, you must read and agree to Wayfern's Terms and Conditions.",
@@ -1680,7 +1673,8 @@
"viewRelease": "View Release",
"later": "Later",
"uploading": "Uploading",
"downloading": "Downloading"
"downloading": "Downloading",
"startingUpdate": "Starting update..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "The corrupt file was deleted. It will be re-downloaded on next attempt.",
"extracting": "Extracting browser files... Please do not close the app.",
"verifying": "Verifying browser files...",
"downloadingRolling": "Downloading rolling release build..."
"downloadingRolling": "Downloading rolling release build...",
"geoipDownloading": "Downloading GeoIP database",
"geoipDownloaded": "GeoIP database downloaded successfully!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "Found {{newVersions}} new versions across {{successfulUpdates}} browsers. Auto-downloads will start shortly.",
"upToDate": "No new browser versions found",
"upToDateDescription": "All browser versions are up to date",
"updateAllFailed": "Failed to update browser versions"
"updateAllFailed": "Failed to update browser versions",
"updateStarted": "{{browser}} update started",
"updateStartedDescription": "Version {{version}} download will begin shortly. Browser launch is disabled until update completes.",
"downloadStarting": "Starting {{browser}} {{version}} download",
"downloadProgressBelow": "Download progress will be shown below...",
"autoDownloadStarted": "Downloading {{browser}} {{version}} automatically. Progress will be shown below."
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "Would you like to send the app to the system tray or quit?",
"minimize": "Minimize to Tray",
"quit": "Quit"
},
"tray": {
"show": "Show Donut Browser",
"quit": "Quit"
},
"browserSupport": {
"endingSoonTitle": "Browser support ending soon",
"endingSoonDescription": "Support for the following profiles will be removed on March 15, 2026: {{profiles}}. Please migrate to Wayfern or Camoufox profiles."
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "Minimizar",
"saving": "Guardando…",
"saved": "Guardado",
"copied": "Copiado"
"copied": "Copiado",
"learnMore": "Más información"
},
"status": {
"active": "Activo",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "Copiar",
"copied": "Copiado"
},
"placeholders": {
"example": "p. ej., {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "Creando...",
"createButton": "Crear"
},
"launchOnLogin": {
"title": "¿Activar inicio al iniciar sesión?",
"description": "Ejecutarse en segundo plano ayuda a mantener vivos los proxies y navegadores.",
"declineButton": "No volver a preguntar",
"declining": "...",
"enableButton": "Activar",
"enableSuccess": "Inicio al iniciar sesión activado",
"enableFailed": "Error al activar el inicio al iniciar sesión",
"declineFailed": "Error al guardar la preferencia",
"tryAgain": "Por favor, inténtalo de nuevo"
},
"wayfernTerms": {
"title": "Términos y condiciones de Wayfern",
"description": "Antes de usar Donut Browser, debes leer y aceptar los Términos y Condiciones de Wayfern.",
@@ -1680,7 +1673,8 @@
"viewRelease": "Ver lanzamiento",
"later": "Más tarde",
"uploading": "Subiendo",
"downloading": "Descargando"
"downloading": "Descargando",
"startingUpdate": "Iniciando actualización..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "El archivo dañado fue eliminado. Se volverá a descargar en el próximo intento.",
"extracting": "Extrayendo archivos del navegador... No cierre la aplicación.",
"verifying": "Verificando archivos del navegador...",
"downloadingRolling": "Descargando compilación rolling release..."
"downloadingRolling": "Descargando compilación rolling release...",
"geoipDownloading": "Descargando base de datos GeoIP",
"geoipDownloaded": "¡Base de datos GeoIP descargada correctamente!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "Se encontraron {{newVersions}} nuevas versiones en {{successfulUpdates}} navegadores. Las descargas automáticas comenzarán pronto.",
"upToDate": "No se encontraron nuevas versiones del navegador",
"upToDateDescription": "Todas las versiones del navegador están actualizadas",
"updateAllFailed": "Error al actualizar las versiones del navegador"
"updateAllFailed": "Error al actualizar las versiones del navegador",
"updateStarted": "Actualización de {{browser}} iniciada",
"updateStartedDescription": "La descarga de la versión {{version}} comenzará en breve. El inicio del navegador está deshabilitado hasta que finalice la actualización.",
"downloadStarting": "Iniciando la descarga de {{browser}} {{version}}",
"downloadProgressBelow": "El progreso de la descarga se mostrará a continuación...",
"autoDownloadStarted": "Descargando {{browser}} {{version}} automáticamente. El progreso se mostrará a continuación."
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "¿Quieres enviar la aplicación a la bandeja del sistema o salir?",
"minimize": "Minimizar a la bandeja",
"quit": "Salir"
},
"tray": {
"show": "Mostrar Donut Browser",
"quit": "Salir"
},
"browserSupport": {
"endingSoonTitle": "El soporte del navegador finalizará pronto",
"endingSoonDescription": "El soporte para los siguientes perfiles se eliminará el 15 de marzo de 2026: {{profiles}}. Migra a perfiles de Wayfern o Camoufox."
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "Réduire",
"saving": "Enregistrement…",
"saved": "Enregistré",
"copied": "Copié"
"copied": "Copié",
"learnMore": "En savoir plus"
},
"status": {
"active": "Actif",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "Copier",
"copied": "Copié"
},
"placeholders": {
"example": "p. ex. {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "Création...",
"createButton": "Créer"
},
"launchOnLogin": {
"title": "Activer le démarrage à la connexion ?",
"description": "Tourner en arrière-plan permet de garder vos proxys et navigateurs actifs.",
"declineButton": "Ne plus demander",
"declining": "...",
"enableButton": "Activer",
"enableSuccess": "Démarrage à la connexion activé",
"enableFailed": "Échec de l'activation du démarrage à la connexion",
"declineFailed": "Échec de l'enregistrement de la préférence",
"tryAgain": "Veuillez réessayer"
},
"wayfernTerms": {
"title": "Conditions générales de Wayfern",
"description": "Avant d'utiliser Donut Browser, vous devez lire et accepter les Conditions Générales de Wayfern.",
@@ -1680,7 +1673,8 @@
"viewRelease": "Voir la version",
"later": "Plus tard",
"uploading": "Envoi",
"downloading": "Téléchargement"
"downloading": "Téléchargement",
"startingUpdate": "Démarrage de la mise à jour..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "Le fichier corrompu a été supprimé. Il sera retéléchargé lors de la prochaine tentative.",
"extracting": "Extraction des fichiers du navigateur... Ne fermez pas l'application.",
"verifying": "Vérification des fichiers du navigateur...",
"downloadingRolling": "Téléchargement de la version rolling release..."
"downloadingRolling": "Téléchargement de la version rolling release...",
"geoipDownloading": "Téléchargement de la base de données GeoIP",
"geoipDownloaded": "Base de données GeoIP téléchargée avec succès !"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "{{newVersions}} nouvelles versions trouvées sur {{successfulUpdates}} navigateurs. Les téléchargements automatiques commenceront sous peu.",
"upToDate": "Aucune nouvelle version de navigateur trouvée",
"upToDateDescription": "Toutes les versions des navigateurs sont à jour",
"updateAllFailed": "Échec de la mise à jour des versions des navigateurs"
"updateAllFailed": "Échec de la mise à jour des versions des navigateurs",
"updateStarted": "Mise à jour de {{browser}} démarrée",
"updateStartedDescription": "Le téléchargement de la version {{version}} va bientôt commencer. Le lancement du navigateur est désactivé jusqu'à la fin de la mise à jour.",
"downloadStarting": "Démarrage du téléchargement de {{browser}} {{version}}",
"downloadProgressBelow": "La progression du téléchargement sera affichée ci-dessous...",
"autoDownloadStarted": "Téléchargement automatique de {{browser}} {{version}}. La progression sera affichée ci-dessous."
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "Voulez-vous envoyer l'application dans la zone de notification ou quitter ?",
"minimize": "Réduire dans la barre d'état",
"quit": "Quitter"
},
"tray": {
"show": "Afficher Donut Browser",
"quit": "Quitter"
},
"browserSupport": {
"endingSoonTitle": "La prise en charge du navigateur prend bientôt fin",
"endingSoonDescription": "La prise en charge des profils suivants sera supprimée le 15 mars 2026 : {{profiles}}. Veuillez migrer vers des profils Wayfern ou Camoufox."
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "最小化",
"saving": "保存中…",
"saved": "保存しました",
"copied": "コピーしました"
"copied": "コピーしました",
"learnMore": "詳細"
},
"status": {
"active": "アクティブ",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "コピー",
"copied": "コピーしました"
},
"placeholders": {
"example": "例: {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "作成中...",
"createButton": "作成"
},
"launchOnLogin": {
"title": "ログイン時に起動しますか?",
"description": "バックグラウンドで実行することで、プロキシとブラウザを維持できます。",
"declineButton": "今後は表示しない",
"declining": "...",
"enableButton": "有効にする",
"enableSuccess": "ログイン時の起動を有効にしました",
"enableFailed": "ログイン時の起動を有効にできませんでした",
"declineFailed": "設定の保存に失敗しました",
"tryAgain": "もう一度お試しください"
},
"wayfernTerms": {
"title": "Wayfern 利用規約",
"description": "Donut Browser を使用する前に、Wayfern の利用規約を読み、同意する必要があります。",
@@ -1680,7 +1673,8 @@
"viewRelease": "リリースを見る",
"later": "後で",
"uploading": "アップロード中",
"downloading": "ダウンロード中"
"downloading": "ダウンロード中",
"startingUpdate": "更新を開始しています..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "破損したファイルは削除されました。次回の試行時に再ダウンロードされます。",
"extracting": "ブラウザファイルを展開中... アプリを閉じないでください。",
"verifying": "ブラウザファイルを検証中...",
"downloadingRolling": "ローリングリリースビルドをダウンロード中..."
"downloadingRolling": "ローリングリリースビルドをダウンロード中...",
"geoipDownloading": "GeoIP データベースをダウンロード中",
"geoipDownloaded": "GeoIP データベースのダウンロードが完了しました!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "{{successfulUpdates}} 個のブラウザに {{newVersions}} 個の新しいバージョンが見つかりました。自動ダウンロードがまもなく開始します。",
"upToDate": "新しいブラウザのバージョンは見つかりませんでした",
"upToDateDescription": "すべてのブラウザバージョンは最新です",
"updateAllFailed": "ブラウザバージョンの更新に失敗しました"
"updateAllFailed": "ブラウザバージョンの更新に失敗しました",
"updateStarted": "{{browser}} の更新を開始しました",
"updateStartedDescription": "バージョン {{version}} のダウンロードがまもなく開始されます。更新が完了するまでブラウザの起動は無効になります。",
"downloadStarting": "{{browser}} {{version}} のダウンロードを開始しています",
"downloadProgressBelow": "ダウンロードの進行状況は下に表示されます...",
"autoDownloadStarted": "{{browser}} {{version}} を自動的にダウンロードしています。進行状況は下に表示されます。"
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "アプリをシステムトレイに格納しますか、それとも終了しますか?",
"minimize": "トレイに格納",
"quit": "終了"
},
"tray": {
"show": "Donut Browser を表示",
"quit": "終了"
},
"browserSupport": {
"endingSoonTitle": "ブラウザのサポートが間もなく終了します",
"endingSoonDescription": "次のプロファイルのサポートは 2026 年 3 月 15 日に削除されます: {{profiles}}。Wayfern または Camoufox のプロファイルに移行してください。"
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "최소화",
"saving": "저장 중…",
"saved": "저장됨",
"copied": "복사됨"
"copied": "복사됨",
"learnMore": "자세히 알아보기"
},
"status": {
"active": "활성",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "복사",
"copied": "복사됨"
},
"placeholders": {
"example": "예: {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "생성 중...",
"createButton": "생성"
},
"launchOnLogin": {
"title": "로그인 시 실행을 활성화하시겠습니까?",
"description": "백그라운드에서 실행하면 프록시와 브라우저를 계속 유지할 수 있습니다.",
"declineButton": "다시 묻지 않음",
"declining": "...",
"enableButton": "활성화",
"enableSuccess": "로그인 시 실행이 활성화되었습니다",
"enableFailed": "로그인 시 실행 활성화 실패",
"declineFailed": "환경 설정 저장 실패",
"tryAgain": "다시 시도하세요"
},
"wayfernTerms": {
"title": "Wayfern 이용 약관",
"description": "도넛 브라우저를 사용하기 전에 Wayfern의 이용 약관을 읽고 동의해야 합니다.",
@@ -1680,7 +1673,8 @@
"viewRelease": "릴리스 보기",
"later": "나중에",
"uploading": "업로드 중",
"downloading": "다운로드 중"
"downloading": "다운로드 중",
"startingUpdate": "업데이트를 시작하는 중..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "손상된 파일이 삭제되었습니다. 다음 시도 시 다시 다운로드됩니다.",
"extracting": "브라우저 파일 압축 해제 중... 앱을 닫지 마세요.",
"verifying": "브라우저 파일 확인 중...",
"downloadingRolling": "롤링 릴리스 빌드 다운로드 중..."
"downloadingRolling": "롤링 릴리스 빌드 다운로드 중...",
"geoipDownloading": "GeoIP 데이터베이스 다운로드 중",
"geoipDownloaded": "GeoIP 데이터베이스를 성공적으로 다운로드했습니다!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "{{successfulUpdates}}개 브라우저에서 {{newVersions}}개의 새 버전을 찾았습니다. 자동 다운로드가 곧 시작됩니다.",
"upToDate": "새 브라우저 버전이 없습니다",
"upToDateDescription": "모든 브라우저 버전이 최신입니다",
"updateAllFailed": "브라우저 버전 업데이트 실패"
"updateAllFailed": "브라우저 버전 업데이트 실패",
"updateStarted": "{{browser}} 업데이트를 시작했습니다",
"updateStartedDescription": "버전 {{version}} 다운로드가 곧 시작됩니다. 업데이트가 완료될 때까지 브라우저 실행이 비활성화됩니다.",
"downloadStarting": "{{browser}} {{version}} 다운로드를 시작하는 중",
"downloadProgressBelow": "다운로드 진행 상황이 아래에 표시됩니다...",
"autoDownloadStarted": "{{browser}} {{version}}을(를) 자동으로 다운로드하는 중입니다. 진행 상황이 아래에 표시됩니다."
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "앱을 시스템 트레이로 보내시겠습니까, 아니면 종료하시겠습니까?",
"minimize": "트레이로 최소화",
"quit": "종료"
},
"tray": {
"show": "Donut Browser 표시",
"quit": "종료"
},
"browserSupport": {
"endingSoonTitle": "브라우저 지원이 곧 종료됩니다",
"endingSoonDescription": "다음 프로필에 대한 지원이 2026년 3월 15일에 제거됩니다: {{profiles}}. Wayfern 또는 Camoufox 프로필로 마이그레이션하세요."
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "Minimizar",
"saving": "Salvando…",
"saved": "Salvo",
"copied": "Copiado"
"copied": "Copiado",
"learnMore": "Saiba mais"
},
"status": {
"active": "Ativo",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "Copiar",
"copied": "Copiado"
},
"placeholders": {
"example": "ex.: {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "Criando...",
"createButton": "Criar"
},
"launchOnLogin": {
"title": "Ativar inicialização no login?",
"description": "Rodar em segundo plano ajuda a manter seus proxies e navegadores ativos.",
"declineButton": "Não perguntar novamente",
"declining": "...",
"enableButton": "Ativar",
"enableSuccess": "Inicialização no login ativada",
"enableFailed": "Falha ao ativar a inicialização no login",
"declineFailed": "Falha ao salvar a preferência",
"tryAgain": "Tente novamente"
},
"wayfernTerms": {
"title": "Termos e condições da Wayfern",
"description": "Antes de usar o Donut Browser, você deve ler e concordar com os Termos e Condições da Wayfern.",
@@ -1680,7 +1673,8 @@
"viewRelease": "Ver lançamento",
"later": "Mais tarde",
"uploading": "Enviando",
"downloading": "Baixando"
"downloading": "Baixando",
"startingUpdate": "Iniciando atualização..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "O arquivo corrompido foi excluído. Será baixado novamente na próxima tentativa.",
"extracting": "Extraindo arquivos do navegador... Não feche o aplicativo.",
"verifying": "Verificando arquivos do navegador...",
"downloadingRolling": "Baixando build rolling release..."
"downloadingRolling": "Baixando build rolling release...",
"geoipDownloading": "Baixando banco de dados GeoIP",
"geoipDownloaded": "Banco de dados GeoIP baixado com sucesso!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "Foram encontradas {{newVersions}} novas versões em {{successfulUpdates}} navegadores. Os downloads automáticos começarão em breve.",
"upToDate": "Nenhuma nova versão de navegador encontrada",
"upToDateDescription": "Todas as versões dos navegadores estão atualizadas",
"updateAllFailed": "Falha ao atualizar as versões dos navegadores"
"updateAllFailed": "Falha ao atualizar as versões dos navegadores",
"updateStarted": "Atualização do {{browser}} iniciada",
"updateStartedDescription": "O download da versão {{version}} começará em breve. O início do navegador está desativado até a atualização ser concluída.",
"downloadStarting": "Iniciando o download do {{browser}} {{version}}",
"downloadProgressBelow": "O progresso do download será mostrado abaixo...",
"autoDownloadStarted": "Baixando {{browser}} {{version}} automaticamente. O progresso será mostrado abaixo."
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "Você deseja enviar o aplicativo para a bandeja do sistema ou sair?",
"minimize": "Minimizar para a bandeja",
"quit": "Sair"
},
"tray": {
"show": "Mostrar Donut Browser",
"quit": "Sair"
},
"browserSupport": {
"endingSoonTitle": "O suporte ao navegador terminará em breve",
"endingSoonDescription": "O suporte aos seguintes perfis será removido em 15 de março de 2026: {{profiles}}. Migre para perfis Wayfern ou Camoufox."
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "Свернуть",
"saving": "Сохраняем…",
"saved": "Сохранено",
"copied": "Скопировано"
"copied": "Скопировано",
"learnMore": "Подробнее"
},
"status": {
"active": "Активен",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "Скопировать",
"copied": "Скопировано"
},
"placeholders": {
"example": "напр., {{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "Создание...",
"createButton": "Создать"
},
"launchOnLogin": {
"title": "Запускать при входе?",
"description": "Работа в фоновом режиме помогает поддерживать прокси и браузеры активными.",
"declineButton": "Больше не спрашивать",
"declining": "...",
"enableButton": "Включить",
"enableSuccess": "Запуск при входе включен",
"enableFailed": "Не удалось включить запуск при входе",
"declineFailed": "Не удалось сохранить настройку",
"tryAgain": "Пожалуйста, попробуйте снова"
},
"wayfernTerms": {
"title": "Условия использования Wayfern",
"description": "Прежде чем использовать Donut Browser, необходимо прочитать и согласиться с Условиями использования Wayfern.",
@@ -1680,7 +1673,8 @@
"viewRelease": "Посмотреть релиз",
"later": "Позже",
"uploading": "Загрузка",
"downloading": "Скачивание"
"downloading": "Скачивание",
"startingUpdate": "Запуск обновления..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "Повреждённый файл удалён. Он будет повторно загружен при следующей попытке.",
"extracting": "Распаковка файлов браузера... Не закрывайте приложение.",
"verifying": "Проверка файлов браузера...",
"downloadingRolling": "Загрузка rolling release сборки..."
"downloadingRolling": "Загрузка rolling release сборки...",
"geoipDownloading": "Загрузка базы данных GeoIP",
"geoipDownloaded": "База данных GeoIP успешно загружена!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "Найдено {{newVersions}} новых версий для {{successfulUpdates}} браузеров. Автоматическая загрузка начнётся в ближайшее время.",
"upToDate": "Новых версий браузеров не найдено",
"upToDateDescription": "Все версии браузеров актуальны",
"updateAllFailed": "Не удалось обновить версии браузеров"
"updateAllFailed": "Не удалось обновить версии браузеров",
"updateStarted": "Обновление {{browser}} началось",
"updateStartedDescription": "Загрузка версии {{version}} скоро начнётся. Запуск браузера отключён до завершения обновления.",
"downloadStarting": "Запуск загрузки {{browser}} {{version}}",
"downloadProgressBelow": "Прогресс загрузки будет показан ниже...",
"autoDownloadStarted": "Автоматическая загрузка {{browser}} {{version}}. Прогресс будет показан ниже."
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "Свернуть приложение в системный трей или выйти?",
"minimize": "Свернуть в трей",
"quit": "Выйти"
},
"tray": {
"show": "Показать Donut Browser",
"quit": "Выход"
},
"browserSupport": {
"endingSoonTitle": "Поддержка браузера скоро завершится",
"endingSoonDescription": "Поддержка следующих профилей будет прекращена 15 марта 2026 г.: {{profiles}}. Перейдите на профили Wayfern или Camoufox."
}
}
+24 -15
View File
@@ -33,7 +33,8 @@
"minimize": "最小化",
"saving": "正在保存…",
"saved": "已保存",
"copied": "已复制"
"copied": "已复制",
"learnMore": "了解更多"
},
"status": {
"active": "活跃",
@@ -99,6 +100,9 @@
"srOnly": {
"copy": "复制",
"copied": "已复制"
},
"placeholders": {
"example": "例如:{{value}}"
}
},
"settings": {
@@ -1524,17 +1528,6 @@
"creatingButton": "正在创建...",
"createButton": "创建"
},
"launchOnLogin": {
"title": "启用登录时启动?",
"description": "在后台运行有助于保持代理和浏览器存活。",
"declineButton": "不再询问",
"declining": "...",
"enableButton": "启用",
"enableSuccess": "已启用登录时启动",
"enableFailed": "启用登录时启动失败",
"declineFailed": "保存偏好失败",
"tryAgain": "请重试"
},
"wayfernTerms": {
"title": "Wayfern 条款和条件",
"description": "在使用 Donut Browser 之前,你必须阅读并同意 Wayfern 的条款和条件。",
@@ -1680,7 +1673,8 @@
"viewRelease": "查看版本",
"later": "稍后",
"uploading": "上传中",
"downloading": "下载中"
"downloading": "下载中",
"startingUpdate": "正在开始更新..."
}
},
"browserDownload": {
@@ -1694,7 +1688,9 @@
"extractionFailedDescription": "损坏的文件已删除。下次尝试时将重新下载。",
"extracting": "正在提取浏览器文件...请不要关闭应用。",
"verifying": "正在验证浏览器文件...",
"downloadingRolling": "正在下载滚动发布版本..."
"downloadingRolling": "正在下载滚动发布版本...",
"geoipDownloading": "正在下载 GeoIP 数据库",
"geoipDownloaded": "GeoIP 数据库下载成功!"
}
},
"versionUpdater": {
@@ -1712,7 +1708,12 @@
"updateSuccessDescription": "在 {{successfulUpdates}} 个浏览器中发现 {{newVersions}} 个新版本。自动下载即将开始。",
"upToDate": "未发现新的浏览器版本",
"upToDateDescription": "所有浏览器版本都是最新的",
"updateAllFailed": "更新浏览器版本失败"
"updateAllFailed": "更新浏览器版本失败",
"updateStarted": "{{browser}} 更新已开始",
"updateStartedDescription": "版本 {{version}} 即将开始下载。更新完成前浏览器启动将被禁用。",
"downloadStarting": "正在开始下载 {{browser}} {{version}}",
"downloadProgressBelow": "下载进度将显示在下方...",
"autoDownloadStarted": "正在自动下载 {{browser}} {{version}}。进度将显示在下方。"
}
},
"profilePassword": {
@@ -1918,5 +1919,13 @@
"description": "您想将应用最小化到系统托盘还是退出?",
"minimize": "最小化到托盘",
"quit": "退出"
},
"tray": {
"show": "显示 Donut Browser",
"quit": "退出"
},
"browserSupport": {
"endingSoonTitle": "浏览器支持即将结束",
"endingSoonDescription": "以下配置文件的支持将于 2026 年 3 月 15 日移除:{{profiles}}。请迁移到 Wayfern 或 Camoufox 配置文件。"
}
}