Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 5x 5x 15x 15x 3x 12x 1x 11x 37x 11x 35x 35x 1x 34x 216x 150x 150x 58x 92x | import { LANGUAGE_MAP } from "i18n/constants";
import { ALMOST_DONE_CUTOFF, SELECTOR_CUTOFF } from "./constants";
export interface WeblateLanguage {
code: string;
translated_percent: number;
}
/**
* Check if a language is production-ready (>= 80% translated)
*/
export function isLanguageProductionReady(
locale: string,
languages: WeblateLanguage[] | undefined,
): boolean {
// English is always production-ready
if (locale === "en") {
return true;
}
if (!languages) {
return false;
}
// Convert locale format (e.g., "es-419" to "es_419" for Weblate)
const weblateCode = locale.replace("-", "_");
const languageStats = languages.find((lang) => lang.code === weblateCode);
return (
!!languageStats && languageStats.translated_percent >= ALMOST_DONE_CUTOFF
);
}
/**
* Filter languages for display in language picker (>= 50% translated by default)
* @param languages - Array of languages with translation stats
* @param showAll - If true, bypasses the SELECTOR_CUTOFF filter (for translators on stage)
*/
export function getAvailableLanguages(
languages: WeblateLanguage[] | undefined,
showAll = false,
): WeblateLanguage[] {
if (!languages) {
return [];
}
return languages
.filter(
(language) =>
LANGUAGE_MAP[language.code.replace("_", "-")] &&
(showAll || language.translated_percent >= SELECTOR_CUTOFF),
)
.sort((a, b) => {
// Sort by translation percentage (>= 80% first), then alphabetically
Iif (
a.translated_percent >= ALMOST_DONE_CUTOFF &&
b.translated_percent < ALMOST_DONE_CUTOFF
)
return -1;
if (
a.translated_percent < ALMOST_DONE_CUTOFF &&
b.translated_percent >= ALMOST_DONE_CUTOFF
)
return 1;
return a.code.localeCompare(b.code);
});
}
|