Merge pull request #590 from saimuelbr/feat-parental-guide-i18n

feat(i18n): implement i18n for ParentalGuideOverlay.tsx
This commit is contained in:
Nayif 2026-03-13 05:51:59 +05:30 committed by GitHub
commit 26a37cb9a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 79 additions and 46 deletions

View file

@ -1,5 +1,6 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native'; import { View, Text, StyleSheet, Dimensions } from 'react-native';
import { useTranslation } from 'react-i18next';
import Animated, { import Animated, {
useSharedValue, useSharedValue,
useAnimatedStyle, useAnimatedStyle,
@ -24,19 +25,9 @@ interface ParentalGuideOverlayProps {
interface WarningItem { interface WarningItem {
label: string; label: string;
severity: string; severity: string;
rawSeverity: string;
} }
const formatLabel = (key: string): string => {
const labels: Record<string, string> = {
nudity: 'Nudity',
violence: 'Violence',
profanity: 'Profanity',
alcohol: 'Alcohol/Drugs',
frightening: 'Frightening',
};
return labels[key] || key;
};
// Row height for calculating line animation // Row height for calculating line animation
const ROW_HEIGHT = 18; const ROW_HEIGHT = 18;
@ -66,6 +57,7 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
episode, episode,
shouldShow, shouldShow,
}) => { }) => {
const { t } = useTranslation();
const { currentTheme } = useTheme(); const { currentTheme } = useTheme();
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const screenWidth = Dimensions.get('window').width; const screenWidth = Dimensions.get('window').width;
@ -89,47 +81,58 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
// Fetch parental guide data // Fetch parental guide data
useEffect(() => { useEffect(() => {
const fetchData = async () => { const fetchData = async () => {
if (!imdbId) return; if (!imdbId) return;
try { try {
let data; let data;
if (type === 'movie') { if (type === "movie") {
data = await parentalGuideService.getMovieGuide(imdbId); data = await parentalGuideService.getMovieGuide(imdbId);
} else if (type === 'series' && season && episode) { } else if (type === "series" && season && episode) {
data = await parentalGuideService.getTVGuide(imdbId, season, episode); data = await parentalGuideService.getTVGuide(
} imdbId,
season,
episode,
);
}
if (data && data.parentalGuide) { if (data && data.parentalGuide) {
const guide = data.parentalGuide; const guide = data.parentalGuide;
const items: WarningItem[] = []; const items: WarningItem[] = [];
Object.entries(guide).forEach(([key, severity]) => { Object.entries(guide).forEach(([key, severity]) => {
if (severity && severity.toLowerCase() !== 'none') { const lowSeverity = severity?.toLowerCase();
items.push({ if (lowSeverity && lowSeverity !== "none") {
label: formatLabel(key), items.push({
severity: severity, label: t(`parentalGuide.labels.${key}`, {
}); defaultValue: key,
} }),
}); severity: t(`parentalGuide.severity.${lowSeverity}`, {
defaultValue: severity,
}),
rawSeverity: lowSeverity,
});
}
});
const severityOrder = { severe: 0, moderate: 1, mild: 2, none: 3 }; const severityOrder = { severe: 0, moderate: 1, mild: 2, none: 3 };
items.sort((a, b) => { items.sort((a, b) => {
const orderA = severityOrder[a.severity.toLowerCase() as keyof typeof severityOrder] ?? 3; // @ts-ignore - fallback to 3 if severity is unrecognized
const orderB = severityOrder[b.severity.toLowerCase() as keyof typeof severityOrder] ?? 3; const orderA = severityOrder[a.rawSeverity] ?? 3;
return orderA - orderB; // @ts-ignore
}); const orderB = severityOrder[b.rawSeverity] ?? 3;
return orderA - orderB;
});
setWarnings(items.slice(0, 5)); setWarnings(items.slice(0, 5));
logger.log('[ParentalGuideOverlay] Loaded warnings:', items.length); }
} } catch (error) {
} catch (error) { logger.error("[ParentalGuideOverlay] Error fetching guide:", error);
logger.error('[ParentalGuideOverlay] Error fetching guide:', error); }
} };
};
fetchData(); fetchData();
}, [imdbId, type, season, episode]); }, [imdbId, type, season, episode, t]);
// Handle show/hide based on shouldShow (controls visibility) // Handle show/hide based on shouldShow (controls visibility)
useEffect(() => { useEffect(() => {

View file

@ -462,6 +462,21 @@
"cancel": "Cancel", "cancel": "Cancel",
"remove": "Remove" "remove": "Remove"
}, },
"parentalGuide": {
"labels": {
"nudity": "Nudity",
"violence": "Violence",
"profanity": "Profanity",
"alcohol": "Alcohol/Drugs",
"frightening": "Frightening"
},
"severity": {
"severe": "Severe",
"moderate": "Moderate",
"mild": "Mild",
"none": "None"
}
},
"addons": { "addons": {
"title": "Addons", "title": "Addons",
"reorder_mode": "Reorder Mode", "reorder_mode": "Reorder Mode",

View file

@ -457,6 +457,21 @@
"cancel": "Cancelar", "cancel": "Cancelar",
"remove": "Remover" "remove": "Remover"
}, },
"parentalGuide": {
"labels": {
"nudity": "Nudez",
"violence": "Violência",
"profanity": "Linguagem Imprópria",
"alcohol": "Álcool/Drogas",
"frightening": "Assustador"
},
"severity": {
"severe": "Grave",
"moderate": "Moderado",
"mild": "Leve",
"none": "Nenhum"
}
},
"addons": { "addons": {
"title": "Addons", "title": "Addons",
"reorder_mode": "Modo de Reordenação", "reorder_mode": "Modo de Reordenação",