mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-10-19 22:17:28 +02:00
feat: Local Storage transfer
This commit is contained in:
1 parent
d594fe4bfd
commit
74c507bd9b
23 files changed
+1552
-38
No files matched your search
@@ -2,8 +2,8 @@
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { save } from "@tauri-apps/plugin-dialog";
|
||||
import { writeTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { open as openDialog, save } from "@tauri-apps/plugin-dialog";
|
||||
import { readTextFile, writeTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { hideOthers } from "aria-hidden";
|
||||
import Color from "color";
|
||||
import { motion, useReducedMotion } from "motion/react";
|
||||
@@ -2403,6 +2403,13 @@ function CookiesSectionInline({
|
||||
: "—"}
|
||||
</p>
|
||||
</div>
|
||||
{profile.ephemeral !== true && !profile.password_protected && (
|
||||
<StorageStateBlock
|
||||
profile={profile}
|
||||
isDisabled={isDisabled}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{domains.length > 0 && (
|
||||
<div className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border border-border bg-muted/40">
|
||||
<p className="shrink-0 border-b border-border px-3 py-2 text-[10px] tracking-wide text-muted-foreground uppercase">
|
||||
@@ -2432,6 +2439,141 @@ function CookiesSectionInline({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The profile's Local Storage with its cookies, as one Playwright
|
||||
* `storageState` file: export it to an automation tool, or import one.
|
||||
*/
|
||||
function StorageStateBlock({
|
||||
profile,
|
||||
isDisabled,
|
||||
t,
|
||||
}: {
|
||||
profile: BrowserProfile;
|
||||
isDisabled: boolean;
|
||||
t: (key: string, options?: Record<string, unknown>) => string;
|
||||
}) {
|
||||
const [stats, setStats] = React.useState<{
|
||||
origins: number;
|
||||
items: number;
|
||||
} | null>(null);
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
|
||||
const loadStats = React.useCallback(async () => {
|
||||
try {
|
||||
setStats(
|
||||
await invoke<{ origins: number; items: number }>(
|
||||
"get_profile_local_storage_stats",
|
||||
{ profileId: profile.id },
|
||||
),
|
||||
);
|
||||
} catch {
|
||||
setStats(null);
|
||||
}
|
||||
}, [profile.id]);
|
||||
|
||||
React.useEffect(() => {
|
||||
void loadStats();
|
||||
}, [loadStats]);
|
||||
|
||||
const handleExport = async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
const content = await invoke<string>("export_profile_storage_state", {
|
||||
profileId: profile.id,
|
||||
includeCookies: true,
|
||||
});
|
||||
const filePath = await save({
|
||||
defaultPath: `${profile.name}_storage_state.json`,
|
||||
filters: [{ name: "JSON", extensions: ["json"] }],
|
||||
});
|
||||
if (!filePath) return;
|
||||
await writeTextFile(filePath, content);
|
||||
showSuccessToast(t("profileInfo.localStorage.exported"));
|
||||
} catch (e) {
|
||||
showErrorToast(translateBackendError(t as never, e));
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleImport = async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
const selected = await openDialog({
|
||||
multiple: false,
|
||||
filters: [{ name: "JSON", extensions: ["json"] }],
|
||||
});
|
||||
if (!selected || typeof selected !== "string") return;
|
||||
const content = await readTextFile(selected);
|
||||
const result = await invoke<{
|
||||
origins: number;
|
||||
items: number;
|
||||
cookies_imported: number;
|
||||
}>("import_profile_storage_state", { profileId: profile.id, content });
|
||||
showSuccessToast(
|
||||
t("profileInfo.localStorage.imported", {
|
||||
items: result.items,
|
||||
origins: result.origins,
|
||||
cookies: result.cookies_imported,
|
||||
}),
|
||||
);
|
||||
void loadStats();
|
||||
} catch (e) {
|
||||
showErrorToast(translateBackendError(t as never, e));
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
data-slot="profile-storage-state"
|
||||
className="flex items-center justify-between gap-3 rounded-md border border-border bg-muted/40 px-3 py-2"
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<p className="text-[10px] tracking-wide text-muted-foreground uppercase">
|
||||
{t("profileInfo.localStorage.title")}
|
||||
</p>
|
||||
<p className="mt-0.5 text-sm" data-slot="profile-local-storage-stats">
|
||||
{stats
|
||||
? t("profileInfo.localStorage.stats", {
|
||||
origins: stats.origins,
|
||||
items: stats.items,
|
||||
})
|
||||
: "—"}
|
||||
</p>
|
||||
<p className="mt-0.5 text-xs text-muted-foreground">
|
||||
{t("profileInfo.localStorage.hint")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-7 gap-1.5"
|
||||
data-slot="storage-state-export"
|
||||
disabled={isDisabled || busy}
|
||||
onClick={() => void handleExport()}
|
||||
>
|
||||
<LuDownload className="size-3.5" />
|
||||
{t("common.buttons.export")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-7 gap-1.5"
|
||||
data-slot="storage-state-import"
|
||||
disabled={isDisabled || busy}
|
||||
onClick={() => void handleImport()}
|
||||
>
|
||||
<LuUpload className="size-3.5" />
|
||||
{t("common.buttons.import")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Inline password set / change / remove form. Replaces three separate
|
||||
// nested modal dialogs with one in-page form that branches on the current
|
||||
// `password_protected` state of the profile.
|
||||
|
||||
@@ -835,6 +835,10 @@
|
||||
"name": "crc-catalog",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
},
|
||||
{
|
||||
"name": "crc32c",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
},
|
||||
{
|
||||
"name": "crc32fast",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
@@ -1247,6 +1251,10 @@
|
||||
"name": "framer-motion",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "fs2",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
},
|
||||
{
|
||||
"name": "futures",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
@@ -1563,6 +1571,10 @@
|
||||
"name": "inout",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
},
|
||||
{
|
||||
"name": "integer-encoding",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "internmap",
|
||||
"license": "ISC"
|
||||
@@ -2391,6 +2403,10 @@
|
||||
"name": "rustls-webpki",
|
||||
"license": "ISC"
|
||||
},
|
||||
{
|
||||
"name": "rusty-leveldb",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "ryu",
|
||||
"license": "Apache-2.0 OR BSL-1.0"
|
||||
@@ -2591,6 +2607,10 @@
|
||||
"name": "smoltcp",
|
||||
"license": "0BSD"
|
||||
},
|
||||
{
|
||||
"name": "snap",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
{
|
||||
"name": "socket2",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "Flüchtige Profile werden beim Schließen des Browsers verworfen, daher können ihnen keine Erweiterungsgruppen zugewiesen werden.",
|
||||
"syncUnavailable": "Flüchtige Profile werden beim Schließen des Browsers verworfen, daher gibt es nichts, was in die Cloud synchronisiert werden könnte.",
|
||||
"hint": "Erstellen Sie ein normales Profil, wenn die Daten erhalten bleiben sollen."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Websites: {{origins}} · Einträge: {{items}}",
|
||||
"hint": "Eine Playwright-storageState-Datei mit den Cookies und dem Local Storage. Zum Importieren muss der Browser geschlossen sein.",
|
||||
"exported": "Speicherzustand exportiert",
|
||||
"imported": "Importiert. Local-Storage-Einträge: {{items}} · Websites: {{origins}} · Cookies: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "Sie können höchstens 100 Vorlagen behalten. Löschen Sie zuerst eine.",
|
||||
"bulkCreateCountInvalid": "Sie können 1 bis {{max}} Profile auf einmal erstellen.",
|
||||
"bulkCreateBusy": "Es werden bereits Profile erstellt. Warten Sie, bis das abgeschlossen ist.",
|
||||
"mcpToolsetUnknown": "Diese Werkzeuggruppe existiert nicht."
|
||||
"mcpToolsetUnknown": "Diese Werkzeuggruppe existiert nicht.",
|
||||
"localStorageEphemeral": "Ein flüchtiges Profil speichert keinen Local Storage auf der Festplatte.",
|
||||
"localStorageProfileProtected": "Dieses Profil ist passwortgeschützt. Sein Local Storage bleibt versiegelt.",
|
||||
"localStorageUnreadable": "Der Local Storage des Profils konnte nicht gelesen werden.",
|
||||
"localStorageUnwritable": "Der Local Storage des Profils konnte nicht geschrieben werden.",
|
||||
"localStorageOriginInvalid": "„{{origin}}“ ist kein Web-Ursprung wie https://example.com.",
|
||||
"localStorageOriginTooLarge": "Der Local Storage für {{origin}} ist größer als die 10 MiB, die eine Website behalten darf.",
|
||||
"localStorageTooManyOrigins": "Die Datei enthält mehr als 10.000 Websites.",
|
||||
"localStorageImportTooLarge": "Die Datei ist größer als 32 MiB.",
|
||||
"storageStateInvalid": "Dies ist keine storageState-Datei.",
|
||||
"localStorageBrowserRunning": "Schließen Sie den Browser, bevor Sie einen Speicherzustand importieren.",
|
||||
"localStorageRemoteSession": "Eine Remote-Sitzung verwendet dieses Profil. Warten Sie, bis ihre Arbeit wieder hier ist."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profile",
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "Ephemeral profiles are discarded when the browser closes, so extension groups cannot be assigned to them.",
|
||||
"syncUnavailable": "Ephemeral profiles are discarded when the browser closes, so there is nothing to sync to the cloud.",
|
||||
"hint": "Create a regular profile if you need this to persist."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Sites: {{origins}} · Items: {{items}}",
|
||||
"hint": "One Playwright storageState file with the cookies and the Local Storage. Import needs the browser closed.",
|
||||
"exported": "Storage state exported",
|
||||
"imported": "Imported. Local Storage items: {{items}} · Sites: {{origins}} · Cookies: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "You can keep at most 100 templates. Delete one first.",
|
||||
"bulkCreateCountInvalid": "You can create from 1 to {{max}} profiles at a time.",
|
||||
"bulkCreateBusy": "Profiles are already being created. Wait until that is done.",
|
||||
"mcpToolsetUnknown": "This tool group does not exist."
|
||||
"mcpToolsetUnknown": "This tool group does not exist.",
|
||||
"localStorageEphemeral": "An ephemeral profile keeps no Local Storage on disk.",
|
||||
"localStorageProfileProtected": "This profile is password-protected. Its Local Storage stays sealed.",
|
||||
"localStorageUnreadable": "The profile's Local Storage could not be read.",
|
||||
"localStorageUnwritable": "The profile's Local Storage could not be written.",
|
||||
"localStorageOriginInvalid": "\"{{origin}}\" is not a web origin like https://example.com.",
|
||||
"localStorageOriginTooLarge": "Local Storage for {{origin}} is larger than the 10 MiB a site may keep.",
|
||||
"localStorageTooManyOrigins": "The file has more than 10,000 sites.",
|
||||
"localStorageImportTooLarge": "The file is larger than 32 MiB.",
|
||||
"storageStateInvalid": "This is not a storageState file.",
|
||||
"localStorageBrowserRunning": "Close the browser before you import a storage state.",
|
||||
"localStorageRemoteSession": "A remote session owns this profile. Wait until its work is back here."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profiles",
|
||||
|
||||
@@ -1621,6 +1621,13 @@
|
||||
"extensionsUnavailable": "Los perfiles efímeros se descartan al cerrar el navegador, así que no se les pueden asignar grupos de extensiones.",
|
||||
"syncUnavailable": "Los perfiles efímeros se descartan al cerrar el navegador, así que no hay nada que sincronizar con la nube.",
|
||||
"hint": "Crea un perfil normal si necesitas que esto se conserve."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Sitios: {{origins}} · Elementos: {{items}}",
|
||||
"hint": "Un archivo storageState de Playwright con las cookies y el Local Storage. Para importar, el navegador debe estar cerrado.",
|
||||
"exported": "Estado de almacenamiento exportado",
|
||||
"imported": "Importado. Elementos de Local Storage: {{items}} · Sitios: {{origins}} · Cookies: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2640,7 +2647,18 @@
|
||||
"templateLimitReached": "Puedes guardar como máximo 100 plantillas. Elimina una primero.",
|
||||
"bulkCreateCountInvalid": "Puedes crear de 1 a {{max}} perfiles a la vez.",
|
||||
"bulkCreateBusy": "Ya se están creando perfiles. Espera a que termine.",
|
||||
"mcpToolsetUnknown": "Este grupo de herramientas no existe."
|
||||
"mcpToolsetUnknown": "Este grupo de herramientas no existe.",
|
||||
"localStorageEphemeral": "Un perfil efímero no guarda Local Storage en el disco.",
|
||||
"localStorageProfileProtected": "Este perfil está protegido con contraseña. Su Local Storage sigue sellado.",
|
||||
"localStorageUnreadable": "No se pudo leer el Local Storage del perfil.",
|
||||
"localStorageUnwritable": "No se pudo escribir el Local Storage del perfil.",
|
||||
"localStorageOriginInvalid": "\"{{origin}}\" no es un origen web como https://example.com.",
|
||||
"localStorageOriginTooLarge": "El Local Storage de {{origin}} supera los 10 MiB que puede guardar un sitio.",
|
||||
"localStorageTooManyOrigins": "El archivo tiene más de 10.000 sitios.",
|
||||
"localStorageImportTooLarge": "El archivo supera los 32 MiB.",
|
||||
"storageStateInvalid": "Este no es un archivo storageState.",
|
||||
"localStorageBrowserRunning": "Cierra el navegador antes de importar un estado de almacenamiento.",
|
||||
"localStorageRemoteSession": "Una sesión remota usa este perfil. Espera a que su trabajo vuelva aquí."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Perfiles",
|
||||
|
||||
@@ -1621,6 +1621,13 @@
|
||||
"extensionsUnavailable": "Les profils éphémères sont supprimés à la fermeture du navigateur : aucun groupe d'extensions ne peut leur être attribué.",
|
||||
"syncUnavailable": "Les profils éphémères sont supprimés à la fermeture du navigateur : il n'y a rien à synchroniser vers le cloud.",
|
||||
"hint": "Créez un profil normal si vous avez besoin de conserver ces données."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Sites : {{origins}} · Éléments : {{items}}",
|
||||
"hint": "Un fichier storageState de Playwright avec les cookies et le Local Storage. L'import nécessite que le navigateur soit fermé.",
|
||||
"exported": "État de stockage exporté",
|
||||
"imported": "Importé. Éléments Local Storage : {{items}} · Sites : {{origins}} · Cookies : {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2640,7 +2647,18 @@
|
||||
"templateLimitReached": "Vous pouvez garder au plus 100 modèles. Supprimez-en un d'abord.",
|
||||
"bulkCreateCountInvalid": "Vous pouvez créer de 1 à {{max}} profils à la fois.",
|
||||
"bulkCreateBusy": "Des profils sont déjà en cours de création. Attendez la fin.",
|
||||
"mcpToolsetUnknown": "Ce groupe d'outils n'existe pas."
|
||||
"mcpToolsetUnknown": "Ce groupe d'outils n'existe pas.",
|
||||
"localStorageEphemeral": "Un profil éphémère ne garde pas de Local Storage sur le disque.",
|
||||
"localStorageProfileProtected": "Ce profil est protégé par un mot de passe. Son Local Storage reste scellé.",
|
||||
"localStorageUnreadable": "Impossible de lire le Local Storage du profil.",
|
||||
"localStorageUnwritable": "Impossible d'écrire le Local Storage du profil.",
|
||||
"localStorageOriginInvalid": "« {{origin}} » n'est pas une origine web comme https://example.com.",
|
||||
"localStorageOriginTooLarge": "Le Local Storage de {{origin}} dépasse les 10 Mio qu'un site peut garder.",
|
||||
"localStorageTooManyOrigins": "Le fichier contient plus de 10 000 sites.",
|
||||
"localStorageImportTooLarge": "Le fichier dépasse 32 Mio.",
|
||||
"storageStateInvalid": "Ce n'est pas un fichier storageState.",
|
||||
"localStorageBrowserRunning": "Fermez le navigateur avant d'importer un état de stockage.",
|
||||
"localStorageRemoteSession": "Une session distante utilise ce profil. Attendez que son travail soit revenu ici."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profils",
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "一時プロファイルはブラウザーを閉じると破棄されるため、拡張機能グループを割り当てられません。",
|
||||
"syncUnavailable": "一時プロファイルはブラウザーを閉じると破棄されるため、クラウドに同期するものはありません。",
|
||||
"hint": "データを保持したい場合は通常のプロファイルを作成してください。"
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "ローカルストレージ",
|
||||
"stats": "サイト: {{origins}} · 項目: {{items}}",
|
||||
"hint": "Cookie とローカルストレージを 1 つの Playwright storageState ファイルにまとめます。インポートするにはブラウザーを閉じてください。",
|
||||
"exported": "ストレージ状態をエクスポートしました",
|
||||
"imported": "インポートしました。ローカルストレージの項目: {{items}} · サイト: {{origins}} · Cookie: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "保存できるテンプレートは最大100件です。先に1件削除してください。",
|
||||
"bulkCreateCountInvalid": "一度に作成できるプロファイルは1〜{{max}}件です。",
|
||||
"bulkCreateBusy": "既にプロファイルを作成中です。完了するまでお待ちください。",
|
||||
"mcpToolsetUnknown": "このツールグループは存在しません。"
|
||||
"mcpToolsetUnknown": "このツールグループは存在しません。",
|
||||
"localStorageEphemeral": "エフェメラルプロファイルはローカルストレージをディスクに保存しません。",
|
||||
"localStorageProfileProtected": "このプロファイルはパスワードで保護されています。ローカルストレージは封印されたままです。",
|
||||
"localStorageUnreadable": "プロファイルのローカルストレージを読み取れませんでした。",
|
||||
"localStorageUnwritable": "プロファイルのローカルストレージに書き込めませんでした。",
|
||||
"localStorageOriginInvalid": "「{{origin}}」は https://example.com のような Web オリジンではありません。",
|
||||
"localStorageOriginTooLarge": "{{origin}} のローカルストレージが、サイトが保存できる 10 MiB を超えています。",
|
||||
"localStorageTooManyOrigins": "ファイルに 10,000 を超えるサイトが含まれています。",
|
||||
"localStorageImportTooLarge": "ファイルが 32 MiB を超えています。",
|
||||
"storageStateInvalid": "これは storageState ファイルではありません。",
|
||||
"localStorageBrowserRunning": "ストレージ状態をインポートする前にブラウザーを閉じてください。",
|
||||
"localStorageRemoteSession": "リモートセッションがこのプロファイルを使用しています。作業がここに戻るまでお待ちください。"
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "プロファイル",
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "임시 프로필은 브라우저를 닫으면 삭제되므로 확장 프로그램 그룹을 지정할 수 없습니다.",
|
||||
"syncUnavailable": "임시 프로필은 브라우저를 닫으면 삭제되므로 클라우드에 동기화할 항목이 없습니다.",
|
||||
"hint": "데이터를 유지하려면 일반 프로필을 만드세요."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "로컬 스토리지",
|
||||
"stats": "사이트: {{origins}} · 항목: {{items}}",
|
||||
"hint": "쿠키와 로컬 스토리지를 하나의 Playwright storageState 파일로 담습니다. 가져오려면 브라우저를 닫아야 합니다.",
|
||||
"exported": "스토리지 상태를 내보냈습니다",
|
||||
"imported": "가져왔습니다. 로컬 스토리지 항목: {{items}} · 사이트: {{origins}} · 쿠키: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "템플릿은 최대 100개까지 보관할 수 있습니다. 먼저 하나를 삭제하세요.",
|
||||
"bulkCreateCountInvalid": "한 번에 1개부터 {{max}}개까지 프로필을 만들 수 있습니다.",
|
||||
"bulkCreateBusy": "이미 프로필을 만드는 중입니다. 끝날 때까지 기다리세요.",
|
||||
"mcpToolsetUnknown": "이 도구 그룹은 없습니다."
|
||||
"mcpToolsetUnknown": "이 도구 그룹은 없습니다.",
|
||||
"localStorageEphemeral": "임시 프로필은 로컬 스토리지를 디스크에 저장하지 않습니다.",
|
||||
"localStorageProfileProtected": "이 프로필은 비밀번호로 보호되어 있습니다. 로컬 스토리지는 봉인된 상태로 유지됩니다.",
|
||||
"localStorageUnreadable": "프로필의 로컬 스토리지를 읽지 못했습니다.",
|
||||
"localStorageUnwritable": "프로필의 로컬 스토리지에 쓰지 못했습니다.",
|
||||
"localStorageOriginInvalid": "\"{{origin}}\"은(는) https://example.com 같은 웹 출처가 아닙니다.",
|
||||
"localStorageOriginTooLarge": "{{origin}}의 로컬 스토리지가 사이트가 보관할 수 있는 10 MiB를 넘습니다.",
|
||||
"localStorageTooManyOrigins": "파일에 사이트가 10,000개 넘게 있습니다.",
|
||||
"localStorageImportTooLarge": "파일이 32 MiB보다 큽니다.",
|
||||
"storageStateInvalid": "storageState 파일이 아닙니다.",
|
||||
"localStorageBrowserRunning": "스토리지 상태를 가져오기 전에 브라우저를 닫으세요.",
|
||||
"localStorageRemoteSession": "원격 세션이 이 프로필을 사용 중입니다. 작업이 이곳으로 돌아올 때까지 기다리세요."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "프로필",
|
||||
|
||||
@@ -1621,6 +1621,13 @@
|
||||
"extensionsUnavailable": "Perfis efêmeros são descartados quando o navegador fecha, portanto não é possível atribuir grupos de extensões a eles.",
|
||||
"syncUnavailable": "Perfis efêmeros são descartados quando o navegador fecha, portanto não há nada para sincronizar com a nuvem.",
|
||||
"hint": "Crie um perfil normal se precisar que isso seja mantido."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Sites: {{origins}} · Itens: {{items}}",
|
||||
"hint": "Um arquivo storageState do Playwright com os cookies e o Local Storage. Para importar, o navegador precisa estar fechado.",
|
||||
"exported": "Estado de armazenamento exportado",
|
||||
"imported": "Importado. Itens de Local Storage: {{items}} · Sites: {{origins}} · Cookies: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2640,7 +2647,18 @@
|
||||
"templateLimitReached": "Você pode manter no máximo 100 modelos. Exclua um primeiro.",
|
||||
"bulkCreateCountInvalid": "Você pode criar de 1 a {{max}} perfis de cada vez.",
|
||||
"bulkCreateBusy": "Já há perfis sendo criados. Aguarde até terminar.",
|
||||
"mcpToolsetUnknown": "Este grupo de ferramentas não existe."
|
||||
"mcpToolsetUnknown": "Este grupo de ferramentas não existe.",
|
||||
"localStorageEphemeral": "Um perfil efêmero não guarda Local Storage no disco.",
|
||||
"localStorageProfileProtected": "Este perfil é protegido por senha. O Local Storage dele continua selado.",
|
||||
"localStorageUnreadable": "Não foi possível ler o Local Storage do perfil.",
|
||||
"localStorageUnwritable": "Não foi possível gravar o Local Storage do perfil.",
|
||||
"localStorageOriginInvalid": "\"{{origin}}\" não é uma origem web como https://example.com.",
|
||||
"localStorageOriginTooLarge": "O Local Storage de {{origin}} passa dos 10 MiB que um site pode guardar.",
|
||||
"localStorageTooManyOrigins": "O arquivo tem mais de 10.000 sites.",
|
||||
"localStorageImportTooLarge": "O arquivo tem mais de 32 MiB.",
|
||||
"storageStateInvalid": "Este não é um arquivo storageState.",
|
||||
"localStorageBrowserRunning": "Feche o navegador antes de importar um estado de armazenamento.",
|
||||
"localStorageRemoteSession": "Uma sessão remota está usando este perfil. Aguarde até o trabalho dela voltar para cá."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Perfis",
|
||||
|
||||
@@ -1632,6 +1632,13 @@
|
||||
"extensionsUnavailable": "Временные профили удаляются при закрытии браузера, поэтому назначить им группы расширений нельзя.",
|
||||
"syncUnavailable": "Временные профили удаляются при закрытии браузера, поэтому синхронизировать с облаком нечего.",
|
||||
"hint": "Создайте обычный профиль, если эти данные должны сохраняться."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Сайты: {{origins}} · Записи: {{items}}",
|
||||
"hint": "Один файл storageState для Playwright с cookie и Local Storage. Для импорта браузер должен быть закрыт.",
|
||||
"exported": "Состояние хранилища экспортировано",
|
||||
"imported": "Импортировано. Записи Local Storage: {{items}} · Сайты: {{origins}} · Cookie: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2660,7 +2667,18 @@
|
||||
"templateLimitReached": "Можно хранить не более 100 шаблонов. Сначала удалите один.",
|
||||
"bulkCreateCountInvalid": "За один раз можно создать от 1 до {{max}} профилей.",
|
||||
"bulkCreateBusy": "Профили уже создаются. Дождитесь окончания.",
|
||||
"mcpToolsetUnknown": "Такой группы инструментов нет."
|
||||
"mcpToolsetUnknown": "Такой группы инструментов нет.",
|
||||
"localStorageEphemeral": "Временный профиль не хранит Local Storage на диске.",
|
||||
"localStorageProfileProtected": "Профиль защищён паролем. Его Local Storage остаётся запечатанным.",
|
||||
"localStorageUnreadable": "Не удалось прочитать Local Storage профиля.",
|
||||
"localStorageUnwritable": "Не удалось записать Local Storage профиля.",
|
||||
"localStorageOriginInvalid": "«{{origin}}» — не веб-источник вида https://example.com.",
|
||||
"localStorageOriginTooLarge": "Local Storage для {{origin}} больше 10 МиБ, которые может хранить сайт.",
|
||||
"localStorageTooManyOrigins": "В файле больше 10 000 сайтов.",
|
||||
"localStorageImportTooLarge": "Файл больше 32 МиБ.",
|
||||
"storageStateInvalid": "Это не файл storageState.",
|
||||
"localStorageBrowserRunning": "Закройте браузер перед импортом состояния хранилища.",
|
||||
"localStorageRemoteSession": "Этот профиль использует удалённая сессия. Дождитесь, пока её работа вернётся сюда."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Профили",
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "Geçici profiller tarayıcı kapandığında silinir, bu yüzden onlara uzantı grubu atanamaz.",
|
||||
"syncUnavailable": "Geçici profiller tarayıcı kapandığında silinir, bu yüzden buluta eşitlenecek bir şey yoktur.",
|
||||
"hint": "Bunun kalıcı olmasını istiyorsanız normal bir profil oluşturun."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Siteler: {{origins}} · Öğeler: {{items}}",
|
||||
"hint": "Çerezleri ve Local Storage'ı tek bir Playwright storageState dosyasında toplar. İçe aktarmak için tarayıcı kapalı olmalıdır.",
|
||||
"exported": "Depolama durumu dışa aktarıldı",
|
||||
"imported": "İçe aktarıldı. Local Storage öğeleri: {{items}} · Siteler: {{origins}} · Çerezler: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "En fazla 100 şablon tutabilirsiniz. Önce birini silin.",
|
||||
"bulkCreateCountInvalid": "Bir seferde 1 ile {{max}} arasında profil oluşturabilirsiniz.",
|
||||
"bulkCreateBusy": "Profiller zaten oluşturuluyor. Bitmesini bekleyin.",
|
||||
"mcpToolsetUnknown": "Bu araç grubu yok."
|
||||
"mcpToolsetUnknown": "Bu araç grubu yok.",
|
||||
"localStorageEphemeral": "Geçici bir profil Local Storage'ı diskte tutmaz.",
|
||||
"localStorageProfileProtected": "Bu profil parolayla korunuyor. Local Storage'ı mühürlü kalır.",
|
||||
"localStorageUnreadable": "Profilin Local Storage'ı okunamadı.",
|
||||
"localStorageUnwritable": "Profilin Local Storage'ına yazılamadı.",
|
||||
"localStorageOriginInvalid": "\"{{origin}}\", https://example.com gibi bir web kaynağı değil.",
|
||||
"localStorageOriginTooLarge": "{{origin}} için Local Storage, bir sitenin tutabileceği 10 MiB'tan büyük.",
|
||||
"localStorageTooManyOrigins": "Dosyada 10.000'den fazla site var.",
|
||||
"localStorageImportTooLarge": "Dosya 32 MiB'tan büyük.",
|
||||
"storageStateInvalid": "Bu bir storageState dosyası değil.",
|
||||
"localStorageBrowserRunning": "Bir depolama durumunu içe aktarmadan önce tarayıcıyı kapatın.",
|
||||
"localStorageRemoteSession": "Bu profili uzak bir oturum kullanıyor. İşi buraya dönene kadar bekleyin."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profiller",
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "Hồ sơ tạm thời bị xoá khi đóng trình duyệt, nên không thể gán nhóm tiện ích mở rộng cho chúng.",
|
||||
"syncUnavailable": "Hồ sơ tạm thời bị xoá khi đóng trình duyệt, nên không có gì để đồng bộ lên đám mây.",
|
||||
"hint": "Hãy tạo hồ sơ thường nếu bạn cần giữ lại dữ liệu này."
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "Local Storage",
|
||||
"stats": "Trang web: {{origins}} · Mục: {{items}}",
|
||||
"hint": "Một tệp storageState của Playwright gồm cookie và Local Storage. Để nhập, trình duyệt phải đóng.",
|
||||
"exported": "Đã xuất trạng thái lưu trữ",
|
||||
"imported": "Đã nhập. Mục Local Storage: {{items}} · Trang web: {{origins}} · Cookie: {{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "Bạn chỉ có thể giữ tối đa 100 mẫu. Hãy xóa một mẫu trước.",
|
||||
"bulkCreateCountInvalid": "Mỗi lần bạn có thể tạo từ 1 đến {{max}} profile.",
|
||||
"bulkCreateBusy": "Đang có profile được tạo. Hãy chờ đến khi xong.",
|
||||
"mcpToolsetUnknown": "Nhóm công cụ này không tồn tại."
|
||||
"mcpToolsetUnknown": "Nhóm công cụ này không tồn tại.",
|
||||
"localStorageEphemeral": "Profile tạm thời không lưu Local Storage trên đĩa.",
|
||||
"localStorageProfileProtected": "Profile này được bảo vệ bằng mật khẩu. Local Storage của nó vẫn được niêm phong.",
|
||||
"localStorageUnreadable": "Không thể đọc Local Storage của profile.",
|
||||
"localStorageUnwritable": "Không thể ghi Local Storage của profile.",
|
||||
"localStorageOriginInvalid": "\"{{origin}}\" không phải nguồn web như https://example.com.",
|
||||
"localStorageOriginTooLarge": "Local Storage của {{origin}} lớn hơn 10 MiB mà một trang web được giữ.",
|
||||
"localStorageTooManyOrigins": "Tệp có hơn 10.000 trang web.",
|
||||
"localStorageImportTooLarge": "Tệp lớn hơn 32 MiB.",
|
||||
"storageStateInvalid": "Đây không phải tệp storageState.",
|
||||
"localStorageBrowserRunning": "Hãy đóng trình duyệt trước khi nhập trạng thái lưu trữ.",
|
||||
"localStorageRemoteSession": "Một phiên từ xa đang dùng profile này. Hãy đợi đến khi công việc của nó trở lại đây."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profile",
|
||||
|
||||
@@ -1610,6 +1610,13 @@
|
||||
"extensionsUnavailable": "临时配置在浏览器关闭时会被丢弃,因此无法为其分配扩展分组。",
|
||||
"syncUnavailable": "临时配置在浏览器关闭时会被丢弃,因此没有可同步到云端的内容。",
|
||||
"hint": "如果需要保留这些数据,请创建普通配置。"
|
||||
},
|
||||
"localStorage": {
|
||||
"title": "本地存储",
|
||||
"stats": "网站:{{origins}} · 条目:{{items}}",
|
||||
"hint": "一个包含 Cookie 和本地存储的 Playwright storageState 文件。导入时浏览器必须关闭。",
|
||||
"exported": "已导出存储状态",
|
||||
"imported": "已导入。本地存储条目:{{items}} · 网站:{{origins}} · Cookie:{{cookies}}"
|
||||
}
|
||||
},
|
||||
"profileTransfer": {
|
||||
@@ -2620,7 +2627,18 @@
|
||||
"templateLimitReached": "最多可保留 100 个模板。请先删除一个。",
|
||||
"bulkCreateCountInvalid": "每次可以创建 1 到 {{max}} 个配置文件。",
|
||||
"bulkCreateBusy": "已在创建配置文件。请等待完成。",
|
||||
"mcpToolsetUnknown": "该工具分组不存在。"
|
||||
"mcpToolsetUnknown": "该工具分组不存在。",
|
||||
"localStorageEphemeral": "临时配置文件不会在磁盘上保存本地存储。",
|
||||
"localStorageProfileProtected": "此配置文件受密码保护,其本地存储保持封存。",
|
||||
"localStorageUnreadable": "无法读取配置文件的本地存储。",
|
||||
"localStorageUnwritable": "无法写入配置文件的本地存储。",
|
||||
"localStorageOriginInvalid": "“{{origin}}”不是 https://example.com 这样的网页来源。",
|
||||
"localStorageOriginTooLarge": "{{origin}} 的本地存储超过了网站可保留的 10 MiB。",
|
||||
"localStorageTooManyOrigins": "文件中的网站超过 10,000 个。",
|
||||
"localStorageImportTooLarge": "文件大于 32 MiB。",
|
||||
"storageStateInvalid": "这不是 storageState 文件。",
|
||||
"localStorageBrowserRunning": "导入存储状态前请关闭浏览器。",
|
||||
"localStorageRemoteSession": "远程会话正在使用此配置文件。请等待其工作回到这里。"
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "配置文件",
|
||||
|
||||
@@ -122,6 +122,17 @@ export type BackendErrorCode =
|
||||
| "API_PORT_UNAVAILABLE"
|
||||
| "MCP_AGENT_UNKNOWN"
|
||||
| "MCP_TOOLSET_UNKNOWN"
|
||||
| "LOCAL_STORAGE_EPHEMERAL"
|
||||
| "LOCAL_STORAGE_PROFILE_PROTECTED"
|
||||
| "LOCAL_STORAGE_UNREADABLE"
|
||||
| "LOCAL_STORAGE_UNWRITABLE"
|
||||
| "LOCAL_STORAGE_ORIGIN_INVALID"
|
||||
| "LOCAL_STORAGE_ORIGIN_TOO_LARGE"
|
||||
| "LOCAL_STORAGE_TOO_MANY_ORIGINS"
|
||||
| "LOCAL_STORAGE_IMPORT_TOO_LARGE"
|
||||
| "STORAGE_STATE_INVALID"
|
||||
| "LOCAL_STORAGE_BROWSER_RUNNING"
|
||||
| "LOCAL_STORAGE_REMOTE_SESSION"
|
||||
| "MCP_AGENT_INSTALL_FAILED"
|
||||
| "MCP_AGENT_REMOVE_FAILED"
|
||||
| "MCP_REMOTE_REQUIRES_SIGN_IN"
|
||||
@@ -636,6 +647,32 @@ export function translateBackendError(t: TFunction, err: unknown): string {
|
||||
return t("backendErrors.mcpRemoteKeyLimit");
|
||||
case "MCP_REMOTE_KEY_UNAVAILABLE":
|
||||
return t("backendErrors.mcpRemoteKeyUnavailable");
|
||||
case "LOCAL_STORAGE_EPHEMERAL":
|
||||
return t("backendErrors.localStorageEphemeral");
|
||||
case "LOCAL_STORAGE_PROFILE_PROTECTED":
|
||||
return t("backendErrors.localStorageProfileProtected");
|
||||
case "LOCAL_STORAGE_UNREADABLE":
|
||||
return t("backendErrors.localStorageUnreadable");
|
||||
case "LOCAL_STORAGE_UNWRITABLE":
|
||||
return t("backendErrors.localStorageUnwritable");
|
||||
case "LOCAL_STORAGE_ORIGIN_INVALID":
|
||||
return t("backendErrors.localStorageOriginInvalid", {
|
||||
origin: parsed.params?.origin ?? "",
|
||||
});
|
||||
case "LOCAL_STORAGE_ORIGIN_TOO_LARGE":
|
||||
return t("backendErrors.localStorageOriginTooLarge", {
|
||||
origin: parsed.params?.origin ?? "",
|
||||
});
|
||||
case "LOCAL_STORAGE_TOO_MANY_ORIGINS":
|
||||
return t("backendErrors.localStorageTooManyOrigins");
|
||||
case "LOCAL_STORAGE_IMPORT_TOO_LARGE":
|
||||
return t("backendErrors.localStorageImportTooLarge");
|
||||
case "STORAGE_STATE_INVALID":
|
||||
return t("backendErrors.storageStateInvalid");
|
||||
case "LOCAL_STORAGE_BROWSER_RUNNING":
|
||||
return t("backendErrors.localStorageBrowserRunning");
|
||||
case "LOCAL_STORAGE_REMOTE_SESSION":
|
||||
return t("backendErrors.localStorageRemoteSession");
|
||||
case "MCP_TOOLSET_UNKNOWN":
|
||||
return t("backendErrors.mcpToolsetUnknown");
|
||||
case "MCP_AGENT_UNKNOWN":
|
||||
|
||||
Reference in new issue
Block a user