Translator: languages that fail to download are tried again
The first start tried the default languages once; a DNS failure at that moment left them missing for good. Languages asked for are now kept as pending in state.json and retried in the background (30 s, doubling to 15 min) until they are in, across restarts; an install from the admin panel joins the same queue. A state from before this, with nothing installed, counts as an unfinished first start. The admin panel shows what is waiting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -300,8 +300,11 @@ function Translation() {
|
||||
queryKey: ["adminTranslation"],
|
||||
queryFn: api.adminTranslation,
|
||||
// While something downloads, follow its progress.
|
||||
refetchInterval: (q) =>
|
||||
Object.keys((q.state.data as AdminTranslation | undefined)?.installing ?? {}).length ? 1500 : false,
|
||||
refetchInterval: (q) => {
|
||||
const d = q.state.data as AdminTranslation | undefined;
|
||||
if (Object.keys(d?.installing ?? {}).length) return 1500;
|
||||
return d?.pending.length ? 10000 : false; // retried in the background
|
||||
},
|
||||
});
|
||||
const done = (data: AdminTranslation) => {
|
||||
queryClient.setQueryData(["adminTranslation"], data);
|
||||
@@ -321,7 +324,12 @@ function Translation() {
|
||||
const busy = install.isPending || remove.isPending;
|
||||
const installing = Object.entries(data?.installing ?? {});
|
||||
const addable = (data?.available ?? [])
|
||||
.filter((c) => !data?.installed.includes(c) && !(c in (data?.installing ?? {})))
|
||||
.filter(
|
||||
(c) =>
|
||||
!data?.installed.includes(c) &&
|
||||
!(c in (data?.installing ?? {})) &&
|
||||
!data?.pending.includes(c),
|
||||
)
|
||||
.sort((a, b) => name(a).localeCompare(name(b), locale));
|
||||
const error = (install.error ?? remove.error) as unknown;
|
||||
|
||||
@@ -377,6 +385,13 @@ function Translation() {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{data.pending.length > 0 && (
|
||||
<p className="text-xs text-amber-600">
|
||||
{t("admin.translationPending", {
|
||||
languages: data.pending.map(name).join(", "),
|
||||
})}
|
||||
</p>
|
||||
)}
|
||||
{Object.entries(data.errors).map(([code, why]) => (
|
||||
<p key={code} className="text-xs text-red-500">
|
||||
{t("admin.translationFailed", { language: name(code) })} {why}
|
||||
|
||||
@@ -701,6 +701,7 @@ export const en = {
|
||||
"admin.translationRemoveTitle": "Remove {language}?",
|
||||
"admin.translationRemoveConfirm": "Its models are deleted. Mail in this language can no longer be translated until it is installed again.",
|
||||
"admin.translationInstalling": "downloading… {percent}%",
|
||||
"admin.translationPending": "Waiting to download: {languages}. Tried again in the background until the models can be fetched.",
|
||||
"admin.translationFailed": "Installing {language} failed:",
|
||||
"admin.translationChoose": "Add a language…",
|
||||
"admin.translationInstall": "Install",
|
||||
|
||||
@@ -712,6 +712,7 @@ export const pl: Catalog = {
|
||||
"admin.translationRemoveTitle": "Usunąć: {language}?",
|
||||
"admin.translationRemoveConfirm": "Jego modele zostaną usunięte. Poczty w tym języku nie będzie można tłumaczyć, dopóki nie zostanie zainstalowany ponownie.",
|
||||
"admin.translationInstalling": "pobieranie… {percent}%",
|
||||
"admin.translationPending": "Czeka na pobranie: {languages}. Ponowne próby trwają w tle, aż modele uda się pobrać.",
|
||||
"admin.translationFailed": "Instalacja nie powiodła się: {language}.",
|
||||
"admin.translationChoose": "Dodaj język…",
|
||||
"admin.translationInstall": "Zainstaluj",
|
||||
|
||||
@@ -49,6 +49,8 @@ export interface AdminTranslation {
|
||||
installed: string[];
|
||||
/** Downloads in progress: bytes done of total (total 0 until known). */
|
||||
installing: Record<string, { done: number; total: number }>;
|
||||
/** Asked for, not downloaded yet: tried again in the background. */
|
||||
pending: string[];
|
||||
/** Languages Mozilla has models for; empty when the catalogue is out of reach. */
|
||||
available: string[];
|
||||
errors: Record<string, string>;
|
||||
|
||||
Reference in New Issue
Block a user