mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 16:51:57 +00:00
Parental Overlay Localization Patch
This commit is contained in:
parent
6bfade4a17
commit
db9d12491d
3 changed files with 343 additions and 279 deletions
|
|
@ -12,6 +12,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|||
import { parentalGuideService } from '../../../services/parentalGuideService';
|
||||
import { logger } from '../../../utils/logger';
|
||||
import { useTheme } from '../../../contexts/ThemeContext';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface ParentalGuideOverlayProps {
|
||||
imdbId: string | undefined;
|
||||
|
|
@ -49,12 +50,17 @@ const WarningItemView: React.FC<{
|
|||
const animatedStyle = useAnimatedStyle(() => ({
|
||||
opacity: opacity.value,
|
||||
}));
|
||||
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Animated.View style={[styles.warningItem, animatedStyle]}>
|
||||
<Text style={[styles.label, { fontSize }]}>{item.label}</Text>
|
||||
<Text style={[styles.label, { fontSize }]}>
|
||||
{/* replace method added to support "Alcohol/Drugs" label */}
|
||||
{t(`overlay_screen.${item.label.toLowerCase().replace('/', '_')}`)}
|
||||
</Text>
|
||||
<Text style={[styles.separator, { fontSize }]}>·</Text>
|
||||
<Text style={[styles.severity, { fontSize }]}>{item.severity}</Text>
|
||||
<Text style={[styles.severity, { fontSize }]}>
|
||||
{t(`overlay_screen.${item.severity.toLowerCase()}`)}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
|
@ -85,7 +91,13 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
const itemOpacity3 = useSharedValue(0);
|
||||
const itemOpacity4 = useSharedValue(0);
|
||||
|
||||
const itemOpacities = [itemOpacity0, itemOpacity1, itemOpacity2, itemOpacity3, itemOpacity4];
|
||||
const itemOpacities = [
|
||||
itemOpacity0,
|
||||
itemOpacity1,
|
||||
itemOpacity2,
|
||||
itemOpacity3,
|
||||
itemOpacity4,
|
||||
];
|
||||
|
||||
// Fetch parental guide data
|
||||
useEffect(() => {
|
||||
|
|
@ -115,8 +127,12 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
|
||||
const severityOrder = { severe: 0, moderate: 1, mild: 2, none: 3 };
|
||||
items.sort((a, b) => {
|
||||
const orderA = severityOrder[a.severity.toLowerCase() as keyof typeof severityOrder] ?? 3;
|
||||
const orderB = severityOrder[b.severity.toLowerCase() as keyof typeof severityOrder] ?? 3;
|
||||
const orderA =
|
||||
severityOrder[a.severity.toLowerCase() as keyof typeof severityOrder] ??
|
||||
3;
|
||||
const orderB =
|
||||
severityOrder[b.severity.toLowerCase() as keyof typeof severityOrder] ??
|
||||
3;
|
||||
return orderA - orderB;
|
||||
});
|
||||
|
||||
|
|
@ -152,19 +168,25 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
const reverseDelay = (count - 1 - i) * 40;
|
||||
itemOpacities[i].value = withDelay(
|
||||
reverseDelay,
|
||||
withTiming(0, { duration: 100 })
|
||||
withTiming(0, { duration: 100 }),
|
||||
);
|
||||
}
|
||||
|
||||
// Line shrinks after items are gone
|
||||
const lineDelay = count * 40 + 50;
|
||||
lineHeight.value = withDelay(lineDelay, withTiming(0, {
|
||||
lineHeight.value = withDelay(
|
||||
lineDelay,
|
||||
withTiming(0, {
|
||||
duration: 200,
|
||||
easing: Easing.in(Easing.cubic),
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
// Container fades out last
|
||||
containerOpacity.value = withDelay(lineDelay + 100, withTiming(0, { duration: 150 }));
|
||||
containerOpacity.value = withDelay(
|
||||
lineDelay + 100,
|
||||
withTiming(0, { duration: 150 }),
|
||||
);
|
||||
|
||||
// Set invisible after all animations complete
|
||||
fadeTimeoutRef.current = setTimeout(() => {
|
||||
|
|
@ -175,14 +197,19 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
|
||||
// When controls are hidden (shouldShow becomes true), show overlay if not already shown for this content
|
||||
// Only show if transitioning from false to true (controls just hidden)
|
||||
if (shouldShow && !prevShouldShowRef.current && warnings.length > 0 && !hasShownRef.current) {
|
||||
if (
|
||||
shouldShow &&
|
||||
!prevShouldShowRef.current &&
|
||||
warnings.length > 0 &&
|
||||
!hasShownRef.current
|
||||
) {
|
||||
hasShownRef.current = true;
|
||||
setIsVisible(true);
|
||||
|
||||
const count = warnings.length;
|
||||
// Line height = (row height * count) + (gap * (count - 1))
|
||||
const gap = 2; // matches styles.itemsContainer gap
|
||||
const totalLineHeight = (count * ROW_HEIGHT) + ((count - 1) * gap);
|
||||
const totalLineHeight = count * ROW_HEIGHT + (count - 1) * gap;
|
||||
|
||||
// Container fade in
|
||||
containerOpacity.value = withTiming(1, { duration: 300 });
|
||||
|
|
@ -197,7 +224,7 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
for (let i = 0; i < count; i++) {
|
||||
itemOpacities[i].value = withDelay(
|
||||
400 + i * 80, // Start after line, stagger each
|
||||
withTiming(1, { duration: 200 })
|
||||
withTiming(1, { duration: 200 }),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -208,19 +235,25 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
const reverseDelay = (count - 1 - i) * 60;
|
||||
itemOpacities[i].value = withDelay(
|
||||
reverseDelay,
|
||||
withTiming(0, { duration: 150 })
|
||||
withTiming(0, { duration: 150 }),
|
||||
);
|
||||
}
|
||||
|
||||
// Line shrinks after items are gone
|
||||
const lineDelay = count * 60 + 100;
|
||||
lineHeight.value = withDelay(lineDelay, withTiming(0, {
|
||||
lineHeight.value = withDelay(
|
||||
lineDelay,
|
||||
withTiming(0, {
|
||||
duration: 300,
|
||||
easing: Easing.in(Easing.cubic),
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
// Container fades out last
|
||||
containerOpacity.value = withDelay(lineDelay + 200, withTiming(0, { duration: 200 }));
|
||||
containerOpacity.value = withDelay(
|
||||
lineDelay + 200,
|
||||
withTiming(0, { duration: 200 }),
|
||||
);
|
||||
|
||||
// Set invisible after all animations complete
|
||||
fadeTimeoutRef.current = setTimeout(() => {
|
||||
|
|
@ -286,9 +319,18 @@ export const ParentalGuideOverlay: React.FC<ParentalGuideOverlayProps> = ({
|
|||
const safeTopOffset = containerPadding;
|
||||
|
||||
return (
|
||||
<Animated.View style={[styles.container, { left: safeLeftOffset, top: safeTopOffset }]} pointerEvents="none">
|
||||
<Animated.View
|
||||
style={[styles.container, { left: safeLeftOffset, top: safeTopOffset }]}
|
||||
pointerEvents="none"
|
||||
>
|
||||
{/* Vertical line - animates height */}
|
||||
<Animated.View style={[styles.line, lineStyle, { backgroundColor: currentTheme.colors.primary, width: lineWidth }]} />
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.line,
|
||||
lineStyle,
|
||||
{ backgroundColor: currentTheme.colors.primary, width: lineWidth },
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Warning items */}
|
||||
<View style={styles.itemsContainer}>
|
||||
|
|
|
|||
|
|
@ -1531,6 +1531,17 @@
|
|||
"library_desc": "Save favorites, track your progress, and sync with Trakt to keep everything organized across devices.",
|
||||
"swipe_to_continue": "Swipe to continue",
|
||||
"skip": "Skip",
|
||||
"get_started":"Get Started"
|
||||
"get_started": "Get Started"
|
||||
},
|
||||
"overlay_screen": {
|
||||
"nudity": "Nudity",
|
||||
"violence": "Violence",
|
||||
"profanity": "Profanity",
|
||||
"alcohol": "Alcohol/Drugs",
|
||||
"frightening": "Frightening",
|
||||
"severe":"severe",
|
||||
"moderate":"moderate",
|
||||
"mild":"mild",
|
||||
"none":"none"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1389,7 +1389,7 @@
|
|||
"theme": {
|
||||
"title": "Temi App",
|
||||
"select_theme": "SELEZIONA TEMA",
|
||||
"create_custom": "Crea Tema Personalizado",
|
||||
"create_custom": "Crea Tema Personalizzato",
|
||||
"options": "OPZIONI",
|
||||
"use_dominant_color": "Usa colore dominante dall'artwork",
|
||||
"categories": {
|
||||
|
|
@ -1532,5 +1532,16 @@
|
|||
"swipe_to_continue": "Scorri per proseguire",
|
||||
"skip": "Salta",
|
||||
"get_started": "Inizia"
|
||||
},
|
||||
"overlay_screen": {
|
||||
"nudity": "Nudità",
|
||||
"violence": "Violenza",
|
||||
"profanity": "Volgarità",
|
||||
"alcohol_drugs": "Alcol/Droga",
|
||||
"frightening": "Paura",
|
||||
"severe": "severa",
|
||||
"moderate": "moderata",
|
||||
"mild": "lieve",
|
||||
"none": "nessuno"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue