catalog parallel fetching and subtitle backgound fix

This commit is contained in:
tapframe 2025-11-03 22:33:33 +05:30
parent 8e34fbb124
commit 2ba7c3c057
4 changed files with 30 additions and 30 deletions

View file

@ -41,19 +41,19 @@ export const MetadataLoadingScreen = forwardRef<MetadataLoadingScreenRef, Metada
const exitAnimation = Animated.parallel([
Animated.timing(sceneOpacity, {
toValue: 0,
duration: 200,
duration: 100,
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
useNativeDriver: true,
}),
Animated.timing(sceneScale, {
toValue: 0.95,
duration: 200,
duration: 100,
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
useNativeDriver: true,
}),
Animated.timing(sceneTranslateY, {
toValue: 8,
duration: 200,
duration: 100,
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
useNativeDriver: true,
}),
@ -74,19 +74,19 @@ export const MetadataLoadingScreen = forwardRef<MetadataLoadingScreenRef, Metada
const sceneAnimation = Animated.parallel([
Animated.timing(sceneOpacity, {
toValue: 1,
duration: 200,
duration: 100,
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
useNativeDriver: true,
}),
Animated.timing(sceneScale, {
toValue: 1,
duration: 200,
duration: 100,
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
useNativeDriver: true,
}),
Animated.timing(sceneTranslateY, {
toValue: 0,
duration: 200,
duration: 100,
easing: Easing.bezier(0.25, 0.1, 0.25, 1.0),
useNativeDriver: true,
}),

View file

@ -1,5 +1,5 @@
import React from 'react';
import { View, Text } from 'react-native';
import { View, Text, Dimensions } from 'react-native';
import Svg, { Text as SvgText, TSpan } from 'react-native-svg';
import { styles } from '../utils/playerStyles';
import { SubtitleSegment } from '../utils/playerTypes';
@ -85,6 +85,13 @@ export const CustomSubtitles: React.FC<CustomSubtitlesProps> = ({
const displayFontSize = subtitleSize * inverseScale;
const displayLineHeight = subtitleSize * lineHeightMultiplier * inverseScale;
const svgHeight = lines.length * displayLineHeight;
// Estimate text width to keep background from spanning full screen when using SVG
const windowWidth = Math.min(Dimensions.get('window').width, Dimensions.get('window').height);
const longestLineChars = Math.max(1, ...lines.map(l => l.length));
const estimatedContentWidth = Math.min(
Math.max(100, Math.ceil(longestLineChars * displayFontSize * 0.6)),
Math.max(140, windowWidth - 40)
);
// Helper to render formatted segments
const renderFormattedText = (segments: SubtitleSegment[], lineIndex: number, keyPrefix: string, isRTL?: boolean, customLetterSpacing?: number) => {
@ -140,14 +147,16 @@ export const CustomSubtitles: React.FC<CustomSubtitlesProps> = ({
backgroundColor: bgColor,
position: 'relative',
alignItems: 'center',
alignSelf: 'center',
maxWidth: windowWidth - 40,
}
]}>
{useCrispSvgOutline ? (
// Crisp outline using react-native-svg (stroke under, fill on top)
<Svg
width={800}
width={estimatedContentWidth}
height={svgHeight}
viewBox={`0 0 1000 ${svgHeight}`}
viewBox={`0 0 ${estimatedContentWidth} ${svgHeight}`}
preserveAspectRatio="xMidYMax meet"
>
{(() => {
@ -159,10 +168,10 @@ export const CustomSubtitles: React.FC<CustomSubtitlesProps> = ({
if (isRTL) {
// For RTL, always use 'end' anchor to position from right edge
anchor = 'end';
x = 1000;
x = estimatedContentWidth;
} else {
anchor = align === 'center' ? 'middle' : align === 'left' ? 'start' : 'end';
x = align === 'center' ? 500 : (align === 'left' ? 0 : 1000);
x = align === 'center' ? (estimatedContentWidth / 2) : (align === 'left' ? 0 : estimatedContentWidth);
}
const baseFontSize = displayFontSize;

View file

@ -65,26 +65,26 @@ export const useMetadataAnimations = (safeAreaTop: number, watchProgress: any) =
try {
// Start with slightly reduced values and animate to full visibility
screenOpacity.value = withTiming(1, {
duration: 250,
duration: 100,
easing: easings.fast
});
heroOpacity.value = withTiming(1, {
duration: 300,
duration: 100,
easing: easings.fast
});
heroScale.value = withSpring(1, ultraFastSpring);
uiElementsOpacity.value = withTiming(1, {
duration: 400,
duration: 100,
easing: easings.natural
});
uiElementsTranslateY.value = withSpring(0, fastSpring);
contentOpacity.value = withTiming(1, {
duration: 350,
duration: 100,
easing: easings.fast
});
} catch (error) {

View file

@ -188,21 +188,12 @@ const HomeScreen = () => {
let catalogIndex = 0;
const catalogQueue: (() => Promise<void>)[] = [];
// Limit concurrent catalog loading to prevent overwhelming the system
const MAX_CONCURRENT_CATALOGS = 1; // Single catalog at a time to minimize heating/memory
let activeCatalogLoads = 0;
const processCatalogQueue = async () => {
while (catalogQueue.length > 0 && activeCatalogLoads < MAX_CONCURRENT_CATALOGS) {
// Launch all catalog loaders in parallel
const launchAllCatalogs = () => {
while (catalogQueue.length > 0) {
const catalogLoader = catalogQueue.shift();
if (catalogLoader) {
activeCatalogLoads++;
catalogLoader().finally(async () => {
activeCatalogLoads--;
// Yield to event loop to avoid JS thread starvation and reduce heating
await new Promise(resolve => setTimeout(resolve, 100));
processCatalogQueue(); // Process next in queue
});
catalogLoader();
}
}
};
@ -318,8 +309,8 @@ const HomeScreen = () => {
setCatalogs(new Array(catalogIndex).fill(null));
});
// Start processing the catalog queue
processCatalogQueue();
// Start all catalog requests in parallel
launchAllCatalogs();
} catch (error) {
if (__DEV__) console.error('[HomeScreen] Error in progressive catalog loading:', error);
InteractionManager.runAfterInteractions(() => {