mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-18 08:57:24 +02:00
refactor: improve ephemeral ux
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
||||
LuSettings,
|
||||
LuShield,
|
||||
LuShieldCheck,
|
||||
LuTimer,
|
||||
LuTrash2,
|
||||
LuUpload,
|
||||
LuUsers,
|
||||
@@ -735,6 +736,13 @@ function ProfileInfoLayout({
|
||||
[visibleActions],
|
||||
);
|
||||
|
||||
// An ephemeral profile is discarded when the browser closes, so it has
|
||||
// nowhere to keep cookies, extensions or a synced copy. The sections were
|
||||
// hidden outright, which left no way to discover that and read as the app
|
||||
// being broken or the plan lacking the feature. Keep them listed and explain.
|
||||
const isEphemeral = profile.ephemeral === true;
|
||||
const isWayfernProfile = profile.browser === "wayfern";
|
||||
|
||||
const deleteAction = findAction("delete");
|
||||
const fingerprintAction = findAction("fingerprint");
|
||||
const cookiesManageAction = findAction("cookiesManage");
|
||||
@@ -814,20 +822,20 @@ function ProfileInfoLayout({
|
||||
cookieCount !== null && cookieCount > 0
|
||||
? cookieCount.toLocaleString()
|
||||
: undefined,
|
||||
hidden: !cookiesAction,
|
||||
hidden: !cookiesAction && !(isEphemeral && isWayfernProfile),
|
||||
},
|
||||
{
|
||||
id: "extensions",
|
||||
icon: <LuPuzzle className="size-3.5" />,
|
||||
label: t("profileInfo.sections.extensions"),
|
||||
badge: extensionGroupName ?? undefined,
|
||||
hidden: !extensionAction,
|
||||
hidden: !extensionAction && !isEphemeral,
|
||||
},
|
||||
{
|
||||
id: "sync",
|
||||
icon: <LuRefreshCw className="size-3.5" />,
|
||||
label: t("profileInfo.sections.sync"),
|
||||
hidden: !syncAction,
|
||||
hidden: !syncAction && !isEphemeral,
|
||||
},
|
||||
{
|
||||
id: "automation",
|
||||
@@ -1073,34 +1081,55 @@ function ProfileInfoLayout({
|
||||
/>
|
||||
)}
|
||||
|
||||
{section === "cookies" && (
|
||||
<CookiesSectionInline
|
||||
profile={profile}
|
||||
isRunning={isRunning}
|
||||
isDisabled={isDisabled}
|
||||
onCopyCookies={cookiesCopyAction?.onClick}
|
||||
onImportCookies={cookiesManageAction?.onClick}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{section === "cookies" &&
|
||||
(isEphemeral ? (
|
||||
<EphemeralSectionNotice
|
||||
title={t("profileInfo.sections.cookies")}
|
||||
description={t("profileInfo.ephemeral.cookiesUnavailable")}
|
||||
t={t}
|
||||
/>
|
||||
) : (
|
||||
<CookiesSectionInline
|
||||
profile={profile}
|
||||
isRunning={isRunning}
|
||||
isDisabled={isDisabled}
|
||||
onCopyCookies={cookiesCopyAction?.onClick}
|
||||
onImportCookies={cookiesManageAction?.onClick}
|
||||
t={t}
|
||||
/>
|
||||
))}
|
||||
|
||||
{section === "extensions" && (
|
||||
<ExtensionsSectionInline
|
||||
profile={profile}
|
||||
isDisabled={isDisabled}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{section === "extensions" &&
|
||||
(isEphemeral ? (
|
||||
<EphemeralSectionNotice
|
||||
title={t("profileInfo.sections.extensions")}
|
||||
description={t("profileInfo.ephemeral.extensionsUnavailable")}
|
||||
t={t}
|
||||
/>
|
||||
) : (
|
||||
<ExtensionsSectionInline
|
||||
profile={profile}
|
||||
isDisabled={isDisabled}
|
||||
t={t}
|
||||
/>
|
||||
))}
|
||||
|
||||
{section === "sync" && (
|
||||
<SyncSectionInline
|
||||
profile={profile}
|
||||
syncMode={syncMode}
|
||||
syncStatus={syncStatus}
|
||||
isDisabled={isDisabled}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{section === "sync" &&
|
||||
(isEphemeral ? (
|
||||
<EphemeralSectionNotice
|
||||
title={t("profileInfo.sections.sync")}
|
||||
description={t("profileInfo.ephemeral.syncUnavailable")}
|
||||
t={t}
|
||||
/>
|
||||
) : (
|
||||
<SyncSectionInline
|
||||
profile={profile}
|
||||
syncMode={syncMode}
|
||||
syncStatus={syncStatus}
|
||||
isDisabled={isDisabled}
|
||||
t={t}
|
||||
/>
|
||||
))}
|
||||
|
||||
{section === "automation" && (
|
||||
<LaunchHookEditor profile={profile} t={t} />
|
||||
@@ -1507,6 +1536,31 @@ function NetworkSectionInline({
|
||||
);
|
||||
}
|
||||
|
||||
/// Explains why a section has nothing to offer on an ephemeral profile.
|
||||
/// Mirrors the locked-fingerprint empty state so the two read as one pattern.
|
||||
function EphemeralSectionNotice({
|
||||
title,
|
||||
description,
|
||||
t,
|
||||
}: {
|
||||
title: string;
|
||||
description: string;
|
||||
t: (key: string, options?: Record<string, unknown>) => string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-3 rounded-lg border p-6 text-center">
|
||||
<LuTimer className="size-4 shrink-0 text-muted-foreground" />
|
||||
<h3 className="text-sm font-medium text-foreground">{title}</h3>
|
||||
<p className="max-w-[48ch] text-sm text-pretty text-muted-foreground">
|
||||
{description}
|
||||
</p>
|
||||
<p className="max-w-[48ch] text-xs text-pretty text-muted-foreground">
|
||||
{t("profileInfo.ephemeral.hint")}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ExtensionsSectionInline({
|
||||
profile,
|
||||
isDisabled,
|
||||
|
||||
@@ -1230,6 +1230,12 @@
|
||||
"syncing": "Syncing",
|
||||
"synced": "Synced",
|
||||
"error": "Error"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Ephemeral profiles are discarded when the browser closes, so there are no cookies to manage here.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2203,7 +2209,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot warms your profiles overnight on a remote machine, so they keep their cookies and their history without your computer being on. It needs a paid plan."
|
||||
"hint": "Cookie Bot warms your profiles overnight on a remote machine, so they keep their cookies and their history without your computer being on."
|
||||
},
|
||||
"empty": {
|
||||
"title": "No profiles are enrolled",
|
||||
|
||||
@@ -1233,6 +1233,12 @@
|
||||
"syncing": "Sincronizando",
|
||||
"synced": "Sincronizado",
|
||||
"error": "Error"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Los perfiles efímeros se descartan al cerrar el navegador, así que aquí no hay cookies que gestionar.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2210,7 +2216,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot calienta tus perfiles por la noche en una máquina remota, así conservan sus cookies y su historial sin que tu ordenador esté encendido. Requiere un plan de pago."
|
||||
"hint": "Cookie Bot calienta tus perfiles por la noche en una máquina remota, así conservan sus cookies y su historial sin que tu ordenador esté encendido."
|
||||
},
|
||||
"empty": {
|
||||
"title": "No hay perfiles inscritos",
|
||||
|
||||
@@ -1233,6 +1233,12 @@
|
||||
"syncing": "Synchronisation",
|
||||
"synced": "Synchronisé",
|
||||
"error": "Erreur"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Les profils éphémères sont supprimés à la fermeture du navigateur : il n'y a donc aucun cookie à gérer ici.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2210,7 +2216,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot chauffe vos profils la nuit sur une machine distante : ils conservent leurs cookies et leur historique sans que votre ordinateur soit allumé. Nécessite un forfait payant."
|
||||
"hint": "Cookie Bot chauffe vos profils la nuit sur une machine distante : ils conservent leurs cookies et leur historique sans que votre ordinateur soit allumé."
|
||||
},
|
||||
"empty": {
|
||||
"title": "Aucun profil inscrit",
|
||||
|
||||
@@ -1230,6 +1230,12 @@
|
||||
"syncing": "同期中",
|
||||
"synced": "同期済み",
|
||||
"error": "エラー"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "一時プロファイルはブラウザーを閉じると破棄されるため、ここで管理できる Cookie はありません。",
|
||||
"extensionsUnavailable": "一時プロファイルはブラウザーを閉じると破棄されるため、拡張機能グループを割り当てられません。",
|
||||
"syncUnavailable": "一時プロファイルはブラウザーを閉じると破棄されるため、クラウドに同期するものはありません。",
|
||||
"hint": "データを保持したい場合は通常のプロファイルを作成してください。"
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2203,7 +2209,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot はリモートマシンで夜間にプロファイルをウォームアップするため、お使いのコンピューターを起動していなくても Cookie と履歴が維持されます。有料プランが必要です。"
|
||||
"hint": "Cookie Bot はリモートマシンで夜間にプロファイルをウォームアップするため、お使いのコンピューターを起動していなくても Cookie と履歴が維持されます。"
|
||||
},
|
||||
"empty": {
|
||||
"title": "登録されたプロファイルはありません",
|
||||
|
||||
@@ -1230,6 +1230,12 @@
|
||||
"syncing": "동기화 중",
|
||||
"synced": "동기화됨",
|
||||
"error": "오류"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "임시 프로필은 브라우저를 닫으면 삭제되므로 여기에서 관리할 쿠키가 없습니다.",
|
||||
"extensionsUnavailable": "임시 프로필은 브라우저를 닫으면 삭제되므로 확장 프로그램 그룹을 지정할 수 없습니다.",
|
||||
"syncUnavailable": "임시 프로필은 브라우저를 닫으면 삭제되므로 클라우드에 동기화할 항목이 없습니다.",
|
||||
"hint": "데이터를 유지하려면 일반 프로필을 만드세요."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2203,7 +2209,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot은 원격 머신에서 밤새 프로필을 예열해, 내 컴퓨터를 켜 두지 않아도 쿠키와 방문 기록이 유지됩니다. 유료 요금제가 필요합니다."
|
||||
"hint": "Cookie Bot은 원격 머신에서 밤새 프로필을 예열해, 내 컴퓨터를 켜 두지 않아도 쿠키와 방문 기록이 유지됩니다."
|
||||
},
|
||||
"empty": {
|
||||
"title": "등록된 프로필이 없습니다",
|
||||
|
||||
@@ -1233,6 +1233,12 @@
|
||||
"syncing": "Sincronizando",
|
||||
"synced": "Sincronizado",
|
||||
"error": "Erro"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Perfis efêmeros são descartados quando o navegador fecha, portanto não há cookies para gerenciar aqui.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2210,7 +2216,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "O Cookie Bot aquece seus perfis durante a noite em uma máquina remota, para que mantenham os cookies e o histórico sem o seu computador ligado. Requer um plano pago."
|
||||
"hint": "O Cookie Bot aquece seus perfis durante a noite em uma máquina remota, para que mantenham os cookies e o histórico sem o seu computador ligado."
|
||||
},
|
||||
"empty": {
|
||||
"title": "Nenhum perfil inscrito",
|
||||
|
||||
@@ -1236,6 +1236,12 @@
|
||||
"syncing": "Синхронизация",
|
||||
"synced": "Синхронизировано",
|
||||
"error": "Ошибка"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Временные профили удаляются при закрытии браузера, поэтому здесь нет cookies для управления.",
|
||||
"extensionsUnavailable": "Временные профили удаляются при закрытии браузера, поэтому назначить им группы расширений нельзя.",
|
||||
"syncUnavailable": "Временные профили удаляются при закрытии браузера, поэтому синхронизировать с облаком нечего.",
|
||||
"hint": "Создайте обычный профиль, если эти данные должны сохраняться."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2217,7 +2223,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot прогревает ваши профили ночью на удалённой машине, чтобы они сохраняли cookies и историю, пока ваш компьютер выключен. Требуется платный тариф."
|
||||
"hint": "Cookie Bot прогревает ваши профили ночью на удалённой машине, чтобы они сохраняли cookies и историю, пока ваш компьютер выключен."
|
||||
},
|
||||
"empty": {
|
||||
"title": "Нет подключённых профилей",
|
||||
|
||||
@@ -1230,6 +1230,12 @@
|
||||
"syncing": "Eşitleniyor",
|
||||
"synced": "Eşitlendi",
|
||||
"error": "Hata"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Geçici profiller tarayıcı kapandığında silinir, bu yüzden burada yönetilecek çerez yoktur.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2203,7 +2209,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot, profillerinizi gece boyunca uzak bir makinede ısıtır; böylece bilgisayarınız açık olmadan çerezlerini ve geçmişlerini korurlar. Ücretli bir plan gerekir."
|
||||
"hint": "Cookie Bot, profillerinizi gece boyunca uzak bir makinede ısıtır; böylece bilgisayarınız açık olmadan çerezlerini ve geçmişlerini korurlar."
|
||||
},
|
||||
"empty": {
|
||||
"title": "Kayıtlı profil yok",
|
||||
|
||||
@@ -1230,6 +1230,12 @@
|
||||
"syncing": "Đang đồng bộ",
|
||||
"synced": "Đã đồng bộ",
|
||||
"error": "Lỗi"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "Hồ sơ tạm thời bị xoá khi đóng trình duyệt, nên ở đây không có cookie nào để quản lý.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2203,7 +2209,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot làm ấm hồ sơ của bạn qua đêm trên máy từ xa, giúp chúng giữ được cookie và lịch sử mà không cần bật máy tính của bạn. Cần gói trả phí."
|
||||
"hint": "Cookie Bot làm ấm hồ sơ của bạn qua đêm trên máy từ xa, giúp chúng giữ được cookie và lịch sử mà không cần bật máy tính của bạn."
|
||||
},
|
||||
"empty": {
|
||||
"title": "Chưa có hồ sơ nào được đăng ký",
|
||||
|
||||
@@ -1230,6 +1230,12 @@
|
||||
"syncing": "同步中",
|
||||
"synced": "已同步",
|
||||
"error": "错误"
|
||||
},
|
||||
"ephemeral": {
|
||||
"cookiesUnavailable": "临时配置在浏览器关闭时会被丢弃,因此这里没有可管理的 Cookie。",
|
||||
"extensionsUnavailable": "临时配置在浏览器关闭时会被丢弃,因此无法为其分配扩展分组。",
|
||||
"syncUnavailable": "临时配置在浏览器关闭时会被丢弃,因此没有可同步到云端的内容。",
|
||||
"hint": "如果需要保留这些数据,请创建普通配置。"
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
@@ -2203,7 +2209,7 @@
|
||||
},
|
||||
"locked": {
|
||||
"title": "Cookie Bot",
|
||||
"hint": "Cookie Bot 在远程机器上通宵养号,无需开着你的电脑也能保住 Cookie 和历史记录。需要付费套餐。"
|
||||
"hint": "Cookie Bot 在远程机器上通宵养号,无需开着你的电脑也能保住 Cookie 和历史记录。"
|
||||
},
|
||||
"empty": {
|
||||
"title": "尚未加入任何配置文件",
|
||||
|
||||
Reference in New Issue
Block a user