mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-10-19 22:17:28 +02:00
fix: first browser download stuck at 0%
This commit is contained in:
1 parent
0789cf0bb9
commit
759263b63f
22 files changed
+291
-49
No files matched your search
@@ -28,6 +28,7 @@ import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
||||
import { useBrowserSetup } from "@/hooks/use-browser-setup";
|
||||
import { useInputModality } from "@/hooks/use-input-modality";
|
||||
import { usePermissions } from "@/hooks/use-permissions";
|
||||
import { translateBackendError } from "@/lib/backend-errors";
|
||||
import { getBrowserDisplayName } from "@/lib/browser-utils";
|
||||
import { getCurrentOS } from "@/lib/platform";
|
||||
|
||||
@@ -460,6 +461,11 @@ export function WelcomeDialog({
|
||||
browser: browserName,
|
||||
})}
|
||||
</p>
|
||||
{setup.error?.detail && (
|
||||
<p className="max-w-[55ch] text-sm/6 text-pretty text-foreground">
|
||||
{translateBackendError(t, setup.error.detail)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* No escape hatch here: a browser must finish downloading
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Event as TauriEvent } from "@tauri-apps/api/event";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import i18n from "@/i18n";
|
||||
import { translateBackendError } from "@/lib/backend-errors";
|
||||
import { getBrowserDisplayName } from "@/lib/browser-utils";
|
||||
import { isOnboardingActive } from "@/lib/onboarding-signal";
|
||||
import {
|
||||
@@ -38,6 +39,7 @@ interface DownloadProgress {
|
||||
speed_bytes_per_sec: number;
|
||||
eta_seconds?: number;
|
||||
stage: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface BrowserVersionsResult {
|
||||
@@ -418,11 +420,13 @@ export function useBrowserDownload() {
|
||||
),
|
||||
{
|
||||
id: `download-error-${progress.browser}-${progress.version}`,
|
||||
description: i18n.t(
|
||||
wasExtracting
|
||||
? "browserDownload.toast.extractionFailedDescription"
|
||||
: "browserDownload.toast.downloadFailedDescription",
|
||||
),
|
||||
description: progress.error
|
||||
? translateBackendError(i18n.t, progress.error)
|
||||
: i18n.t(
|
||||
wasExtracting
|
||||
? "browserDownload.toast.extractionFailedDescription"
|
||||
: "browserDownload.toast.downloadFailedDescription",
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ interface DownloadProgress {
|
||||
speed_bytes_per_sec: number;
|
||||
eta_seconds?: number | null;
|
||||
stage: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export type SetupPhase = "downloading" | "extracting" | "ready" | "error";
|
||||
@@ -25,6 +26,8 @@ export type SetupErrorStage =
|
||||
|
||||
export interface SetupError {
|
||||
stage: SetupErrorStage;
|
||||
/** The backend's reason, coded or plain, when it sent one. */
|
||||
detail?: string;
|
||||
}
|
||||
|
||||
// The backend reports real extraction percentages for most archive formats
|
||||
@@ -216,7 +219,10 @@ export function useBrowserSetup(browser: string, active: boolean) {
|
||||
doneRef.current = true;
|
||||
finishExtraction();
|
||||
setPhase("error");
|
||||
setError({ stage: toErrorStage(lastStageRef.current) });
|
||||
setError({
|
||||
stage: toErrorStage(lastStageRef.current),
|
||||
detail: p.error,
|
||||
});
|
||||
break;
|
||||
case "cancelled":
|
||||
// Treat a cancellation like an error so the dialog can offer retry.
|
||||
|
||||
@@ -2350,7 +2350,8 @@
|
||||
"syncDisplayUnavailable": "The display size could not be read, so the windows cannot be arranged.",
|
||||
"syncDisplayTooSmall": "The display is too small for {{windows}} windows in that layout.",
|
||||
"syncArrangeFailed": "No window could be moved.",
|
||||
"extensionPathInvalid": "That path is not allowed: it contains '..'."
|
||||
"extensionPathInvalid": "That path is not allowed: it contains '..'.",
|
||||
"systemProxyUnreachable": "Donut could not connect through the system proxy {{proxy}}. Fix or turn off the proxy in your system network settings, then try again."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profiles",
|
||||
|
||||
@@ -2360,7 +2360,8 @@
|
||||
"syncDisplayUnavailable": "No se pudo leer el tamaño de la pantalla, así que las ventanas no se pueden ordenar.",
|
||||
"syncDisplayTooSmall": "La pantalla es demasiado pequeña para {{windows}} ventanas en esa disposición.",
|
||||
"syncArrangeFailed": "No se pudo mover ninguna ventana.",
|
||||
"extensionPathInvalid": "Esa ruta no está permitida: contiene '..'."
|
||||
"extensionPathInvalid": "Esa ruta no está permitida: contiene '..'.",
|
||||
"systemProxyUnreachable": "Donut no pudo conectarse a través del proxy del sistema {{proxy}}. Corrige o desactiva el proxy en la configuración de red del sistema e inténtalo de nuevo."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Perfiles",
|
||||
|
||||
@@ -2360,7 +2360,8 @@
|
||||
"syncDisplayUnavailable": "La taille de l'écran n'a pas pu être lue, les fenêtres ne peuvent donc pas être rangées.",
|
||||
"syncDisplayTooSmall": "L'écran est trop petit pour {{windows}} fenêtres dans cette disposition.",
|
||||
"syncArrangeFailed": "Aucune fenêtre n'a pu être déplacée.",
|
||||
"extensionPathInvalid": "Ce chemin n'est pas autorisé : il contient « .. »."
|
||||
"extensionPathInvalid": "Ce chemin n'est pas autorisé : il contient « .. ».",
|
||||
"systemProxyUnreachable": "Donut n'a pas pu se connecter via le proxy système {{proxy}}. Corrigez ou désactivez le proxy dans les paramètres réseau de votre système, puis réessayez."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profils",
|
||||
|
||||
@@ -2350,7 +2350,8 @@
|
||||
"syncDisplayUnavailable": "画面の大きさを読み取れなかったため、ウィンドウを並べられません。",
|
||||
"syncDisplayTooSmall": "その配置で {{windows}} 個のウィンドウを並べるには画面が小さすぎます。",
|
||||
"syncArrangeFailed": "動かせたウィンドウはありませんでした。",
|
||||
"extensionPathInvalid": "そのパスは使用できません。'..' が含まれています。"
|
||||
"extensionPathInvalid": "そのパスは使用できません。'..' が含まれています。",
|
||||
"systemProxyUnreachable": "システムプロキシ {{proxy}} 経由で接続できませんでした。システムのネットワーク設定でプロキシを修正するか無効にしてから、もう一度お試しください。"
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "プロファイル",
|
||||
|
||||
@@ -2350,7 +2350,8 @@
|
||||
"syncDisplayUnavailable": "화면 크기를 읽지 못해 창을 정렬할 수 없습니다.",
|
||||
"syncDisplayTooSmall": "그 배치로 창 {{windows}}개를 놓기에는 화면이 너무 작습니다.",
|
||||
"syncArrangeFailed": "옮겨진 창이 없습니다.",
|
||||
"extensionPathInvalid": "그 경로는 사용할 수 없습니다. '..'이 포함되어 있습니다."
|
||||
"extensionPathInvalid": "그 경로는 사용할 수 없습니다. '..'이 포함되어 있습니다.",
|
||||
"systemProxyUnreachable": "시스템 프록시 {{proxy}}를 통해 연결하지 못했습니다. 시스템 네트워크 설정에서 프록시를 수정하거나 끈 다음 다시 시도하세요."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "프로필",
|
||||
|
||||
@@ -2360,7 +2360,8 @@
|
||||
"syncDisplayUnavailable": "Não foi possível ler o tamanho do ecrã, por isso as janelas não podem ser organizadas.",
|
||||
"syncDisplayTooSmall": "O ecrã é demasiado pequeno para {{windows}} janelas nessa disposição.",
|
||||
"syncArrangeFailed": "Não foi possível mover nenhuma janela.",
|
||||
"extensionPathInvalid": "Esse caminho não é permitido: contém '..'."
|
||||
"extensionPathInvalid": "Esse caminho não é permitido: contém '..'.",
|
||||
"systemProxyUnreachable": "O Donut não conseguiu se conectar pelo proxy do sistema {{proxy}}. Corrija ou desative o proxy nas configurações de rede do sistema e tente novamente."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Perfis",
|
||||
|
||||
@@ -2370,7 +2370,8 @@
|
||||
"syncDisplayUnavailable": "Не удалось узнать размер экрана, поэтому окна не расставить.",
|
||||
"syncDisplayTooSmall": "Экран слишком мал для {{windows}} окон в таком расположении.",
|
||||
"syncArrangeFailed": "Ни одно окно не удалось переместить.",
|
||||
"extensionPathInvalid": "Этот путь недопустим: он содержит «..»."
|
||||
"extensionPathInvalid": "Этот путь недопустим: он содержит «..».",
|
||||
"systemProxyUnreachable": "Donut не удалось подключиться через системный прокси {{proxy}}. Исправьте или отключите прокси в сетевых настройках системы и повторите попытку."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Профили",
|
||||
|
||||
@@ -2350,7 +2350,8 @@
|
||||
"syncDisplayUnavailable": "Ekran boyutu okunamadı, bu yüzden pencereler yerleştirilemiyor.",
|
||||
"syncDisplayTooSmall": "Ekran, o düzende {{windows}} pencere için fazla küçük.",
|
||||
"syncArrangeFailed": "Hiçbir pencere taşınamadı.",
|
||||
"extensionPathInvalid": "Bu yol kullanılamaz: '..' içeriyor."
|
||||
"extensionPathInvalid": "Bu yol kullanılamaz: '..' içeriyor.",
|
||||
"systemProxyUnreachable": "Donut, {{proxy}} sistem proxy'si üzerinden bağlanamadı. Sistem ağ ayarlarınızda proxy'yi düzeltin veya kapatın, ardından yeniden deneyin."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profiller",
|
||||
|
||||
@@ -2350,7 +2350,8 @@
|
||||
"syncDisplayUnavailable": "Không đọc được kích thước màn hình nên không xếp được cửa sổ.",
|
||||
"syncDisplayTooSmall": "Màn hình quá nhỏ cho {{windows}} cửa sổ theo cách xếp đó.",
|
||||
"syncArrangeFailed": "Không cửa sổ nào được di chuyển.",
|
||||
"extensionPathInvalid": "Đường dẫn đó không được phép: nó chứa '..'."
|
||||
"extensionPathInvalid": "Đường dẫn đó không được phép: nó chứa '..'.",
|
||||
"systemProxyUnreachable": "Donut không thể kết nối qua proxy hệ thống {{proxy}}. Hãy sửa hoặc tắt proxy trong cài đặt mạng của hệ thống rồi thử lại."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profile",
|
||||
|
||||
@@ -2350,7 +2350,8 @@
|
||||
"syncDisplayUnavailable": "无法读取显示器尺寸,因此不能排列窗口。",
|
||||
"syncDisplayTooSmall": "显示器太小,无法以该布局排列 {{windows}} 个窗口。",
|
||||
"syncArrangeFailed": "没有窗口被移动。",
|
||||
"extensionPathInvalid": "该路径不允许使用:它包含“..”。"
|
||||
"extensionPathInvalid": "该路径不允许使用:它包含“..”。",
|
||||
"systemProxyUnreachable": "Donut 无法通过系统代理 {{proxy}} 连接。请在系统网络设置中修正或关闭该代理,然后重试。"
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "配置文件",
|
||||
|
||||
@@ -64,6 +64,7 @@ export type BackendErrorCode =
|
||||
| "UPDATE_CHECKSUM_MISMATCH"
|
||||
| "BROWSER_CHECKSUM_UNAVAILABLE"
|
||||
| "BROWSER_CHECKSUM_MISMATCH"
|
||||
| "SYSTEM_PROXY_UNREACHABLE"
|
||||
| "UPDATE_PROFILES_RUNNING"
|
||||
| "UPDATE_PREPARATION_FAILED"
|
||||
| "PROFILE_NAME_EXISTS"
|
||||
@@ -441,6 +442,10 @@ export function translateBackendError(t: TFunction, err: unknown): string {
|
||||
browser: parsed.params?.browser ?? "",
|
||||
version: parsed.params?.version ?? "",
|
||||
});
|
||||
case "SYSTEM_PROXY_UNREACHABLE":
|
||||
return t("backendErrors.systemProxyUnreachable", {
|
||||
proxy: parsed.params?.proxy ?? "",
|
||||
});
|
||||
case "BROWSER_CHECKSUM_MISMATCH":
|
||||
return t("backendErrors.browserChecksumMismatch", {
|
||||
browser: parsed.params?.browser ?? "",
|
||||
|
||||
Reference in new issue
Block a user