i18n(app-svep) + i18n-vakt: hela mobil-UI:t översatt + CI-vakt mot regress
- Svepte 51 hårdkodade strängar -> t() över konto, sök/bläddra, sparade recept, kök, planera, skanna, byt måltid, inköp, minne, cooking, api-fel (+ locLabel/ kategorier via nycklar). 47 nya nycklar, översatta till alla 12 språk. - NY: apps/mobile/scripts/i18n-check.mjs (i18n:check) – fäller bygget om ett språk saknar en nyckel, en använd nyckel saknas, eller det finns hårdkodad UI-text. Wire:ad i CI (.github/workflows/ci.yml) efter typecheck. => 'lägg till språk' blir: kör vakten, den listar exakt vad som fattas. Aldrig mer leta för hand. - Prettier-fixade 5 filer från tidigare leveranser så format:check blir grön. - submit-recipe fri-text-payload + firebase dev-stubs markerade // i18n-ignore. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -251,40 +251,40 @@ export default function CookingScreen() {
|
||||
{step?.temperatureC ? ` (${step.temperatureC} °C)` : ""}
|
||||
</Text>
|
||||
{step?.tip && <Small>💡 {step.tip}</Small>}
|
||||
<Pressable
|
||||
onPress={() => setShowIngredients((v) => !v)}
|
||||
hitSlop={8}
|
||||
style={{ alignSelf: "flex-start" }}
|
||||
>
|
||||
<Small style={{ color: colors.primaryDark, fontWeight: "600" }}>
|
||||
{showIngredients ? "▾ " : "▸ "}📋 {t("recipe.ingredients")}
|
||||
</Small>
|
||||
</Pressable>
|
||||
{showIngredients && (
|
||||
<View
|
||||
style={{
|
||||
maxHeight: 200,
|
||||
backgroundColor: colors.surfaceAlt,
|
||||
borderRadius: 12,
|
||||
padding: spacing.md,
|
||||
}}
|
||||
<Pressable
|
||||
onPress={() => setShowIngredients((v) => !v)}
|
||||
hitSlop={8}
|
||||
style={{ alignSelf: "flex-start" }}
|
||||
>
|
||||
<ScrollView>
|
||||
{recipe.ingredients.map((ing) => {
|
||||
const scaledQty = (ing.quantity * portionsCooked) / recipe.portions;
|
||||
return (
|
||||
<Row key={ing.id} style={{ justifyContent: "space-between" }}>
|
||||
<Body>
|
||||
{ing.displayNameSv}
|
||||
{ing.optional ? " (valfritt)" : ""}
|
||||
</Body>
|
||||
<Small>{formatQuantity(scaledQty, ing.unit)}</Small>
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
<Small style={{ color: colors.primaryDark, fontWeight: "600" }}>
|
||||
{showIngredients ? "▾ " : "▸ "}📋 {t("recipe.ingredients")}
|
||||
</Small>
|
||||
</Pressable>
|
||||
{showIngredients && (
|
||||
<View
|
||||
style={{
|
||||
maxHeight: 200,
|
||||
backgroundColor: colors.surfaceAlt,
|
||||
borderRadius: 12,
|
||||
padding: spacing.md,
|
||||
}}
|
||||
>
|
||||
<ScrollView>
|
||||
{recipe.ingredients.map((ing) => {
|
||||
const scaledQty = (ing.quantity * portionsCooked) / recipe.portions;
|
||||
return (
|
||||
<Row key={ing.id} style={{ justifyContent: "space-between" }}>
|
||||
<Body>
|
||||
{ing.displayNameSv}
|
||||
{ing.optional ? " (valfritt)" : ""}
|
||||
</Body>
|
||||
<Small>{formatQuantity(scaledQty, ing.unit)}</Small>
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{step?.timerSeconds != null && (
|
||||
<View
|
||||
@@ -298,7 +298,7 @@ export default function CookingScreen() {
|
||||
<Text style={{ fontSize: 22, fontWeight: "700", color: colors.primaryDark }}>
|
||||
⏱ {formatTime(step.timerSeconds)}
|
||||
</Text>
|
||||
<Small>Ungefärlig tid för steget – använd din telefons egen timer.</Small>
|
||||
<Small>{t("cooking.timerHint")}</Small>
|
||||
</View>
|
||||
)}
|
||||
<Small>{t("cooking.keepAwake")}</Small>
|
||||
|
||||
Reference in New Issue
Block a user