fix for Kitsu and Mal content being still incorrectly requested

This commit is contained in:
skoruppa 2026-03-02 09:15:02 +01:00
parent 84f8fc94fc
commit 5bbc2abe8b
4 changed files with 73 additions and 43 deletions

View file

@ -1877,6 +1877,7 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
}
// Get TMDB ID for external sources and determine the correct ID for Stremio addons
const isImdb = id.startsWith('tt');
if (__DEV__) console.log('🔍 [loadEpisodeStreams] Getting TMDB ID for:', id);
let tmdbId;
let stremioEpisodeId = episodeId; // Default to original episode ID
@ -1901,19 +1902,25 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
const cleanEpisodeId = episodeId.replace(/^series:/, '');
const parts = cleanEpisodeId.split(':');
if (parts[0] === 'kitsu' && parts.length === 3) {
// kitsu:animeId:episode — no season segment
if (isImdb && parts.length === 3) {
// Format: ttXXX:season:episode
showIdStr = parts[0];
seasonNum = parts[1];
episodeNum = parts[2];
} else if (!isImdb && parts.length === 3) {
// Format: prefix:id:episode (no season for MAL/Kitsu/etc)
showIdStr = `${parts[0]}:${parts[1]}`;
episodeNum = parts[2];
seasonNum = '';
} else if (parts.length >= 3) {
episodeNum = parts.pop() || '';
seasonNum = parts.pop() || '';
showIdStr = parts.join(':');
} else if (parts.length === 2) {
showIdStr = parts[0];
episodeNum = parts[1];
seasonNum = '';
} else if (parts.length >= 4) {
// Format: prefix:id:season:episode - it is possible that some addons use it
episodeNum = parts.pop() || '';
seasonNum = parts.pop() || '';
showIdStr = parts.join(':');
}
if (__DEV__) console.log(`🔍 [loadEpisodeStreams] Parsed ID: show=${showIdStr}, s=${seasonNum}, e=${episodeNum}`);
@ -1976,7 +1983,7 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
if (__DEV__) console.log('⚠️ [loadEpisodeStreams] Failed to convert TMDB to IMDb, using TMDB episode ID:', error);
}
}
} else if (id.startsWith('tt')) {
} else if (isImdb) {
// This is already an IMDB ID, perfect for Stremio
if (settings.enrichMetadataWithTMDB) {
if (__DEV__) console.log('📝 [loadEpisodeStreams] Converting IMDB ID to TMDB ID...');

View file

@ -586,13 +586,17 @@ const MetadataScreen: React.FC = () => {
const handleShowStreams = useCallback(() => {
const { watchProgress } = watchProgressData;
const isImdb = id.startsWith('tt');
// Ensure trailer stops immediately before navigating to Streams
try { pauseTrailer(); } catch { }
// Helper to build episodeId from episode object
const buildEpisodeId = (ep: any): string => {
return ep.stremioId || `${id}:${ep.season_number}:${ep.episode_number}`;
if (ep.stremioId) return ep.stremioId;
return isImdb
? `${id}:${ep.season_number}:${ep.episode_number}`
: `${id}:${ep.episode_number}`;
};
if (Object.keys(groupedEpisodes).length > 0) {
@ -611,38 +615,28 @@ const MetadataScreen: React.FC = () => {
const parts = watchProgress.episodeId.split(':');
if (parts.length === 3) {
// showId:season:episode
currentSeason = parseInt(parts[1], 10);
currentEpisode = parseInt(parts[2], 10);
} else if (parts.length === 2) {
// season:episode
currentSeason = parseInt(parts[0], 10);
currentEpisode = parseInt(parts[1], 10);
} else {
// pattern like s5e01
const match = watchProgress.episodeId.match(/s(\d+)e(\d+)/i);
if (match) {
currentSeason = parseInt(match[1], 10);
currentEpisode = parseInt(match[2], 10);
if (isImdb) {
if (parts.length === 3) {
currentSeason = parseInt(parts[1], 10);
currentEpisode = parseInt(parts[2], 10);
} else if (parts.length === 2) {
currentEpisode = parseInt(parts[1], 10);
}
} else {
currentEpisode = parts.length === 3 ? parseInt(parts[2], 10) : null;
}
if (currentSeason !== null && currentEpisode !== null) {
// DIRECT APPROACH: Just create the next episode ID directly
// This ensures we navigate to the next episode even if it's not yet in our episodes array
const nextEpisodeId = `${id}:${currentSeason}:${currentEpisode + 1}`;
if (__DEV__) console.log(`[MetadataScreen] Created next episode ID directly: ${nextEpisodeId}`);
// Still try to find the episode in our list to verify it exists
const nextEpisodeExists = episodes.some(ep =>
ep.season_number === currentSeason && ep.episode_number === (currentEpisode + 1)
);
if (currentEpisode !== null) {
const nextEpisodeId = isImdb
? `${id}:${currentSeason || episodes[0]?.season_number || 1}:${currentEpisode + 1}`
: `${id}:${currentEpisode + 1}`;
if (__DEV__) console.log(`[MetadataScreen] Created next episode ID: ${nextEpisodeId}`);
const nextEpisodeExists = episodes.some(ep => ep.episode_number === (currentEpisode + 1));
if (nextEpisodeExists) {
if (__DEV__) console.log(`[MetadataScreen] Verified next episode S${currentSeason}E${currentEpisode + 1} exists in episodes list`);
if (__DEV__) console.log(`[MetadataScreen] Verified next episode exists`);
} else {
if (__DEV__) console.log(`[MetadataScreen] Warning: Next episode S${currentSeason}E${currentEpisode + 1} not found in episodes list, but proceeding anyway`);
if (__DEV__) console.log(`[MetadataScreen] Warning: Next episode not found`);
}
targetEpisodeId = nextEpisodeId;
@ -656,10 +650,14 @@ const MetadataScreen: React.FC = () => {
}
if (targetEpisodeId) {
// Ensure the episodeId has showId prefix (id:season:episode)
// Ensure the episodeId has showId prefix (id:season:episode or id:episode)
const epParts = targetEpisodeId.split(':');
let normalizedEpisodeId = targetEpisodeId;
if (epParts.length === 2) {
if (epParts.length === 2 && !isImdb) {
normalizedEpisodeId = `${id}:${epParts[1]}`;
}
else if (epParts.length === 2 && isImdb) {
normalizedEpisodeId = `${id}:${epParts[0]}:${epParts[1]}`;
}
if (__DEV__) console.log(`[MetadataScreen] Navigating to streams with episodeId: ${normalizedEpisodeId}`);
@ -672,7 +670,9 @@ const MetadataScreen: React.FC = () => {
let fallbackEpisodeId = episodeId;
if (episodeId && episodeId.split(':').length === 2) {
const p = episodeId.split(':');
fallbackEpisodeId = `${id}:${p[0]}:${p[1]}`;
if (!p[0].startsWith('tt')) {
fallbackEpisodeId = isImdb ? `${id}:${p[0]}:${p[1]}` : `${id}:${p[1]}`;
}
}
if (__DEV__) console.log(`[MetadataScreen] Navigating with fallback episodeId: ${fallbackEpisodeId}`);
navigation.navigate('Streams', { id, type, episodeId: fallbackEpisodeId });
@ -682,7 +682,16 @@ const MetadataScreen: React.FC = () => {
if (!isScreenFocused) return;
if (__DEV__) console.log('[MetadataScreen] Selected Episode:', episode.episode_number, episode.season_number);
const episodeId = episode.stremioId || `${id}:${episode.season_number}:${episode.episode_number}`;
let episodeId: string;
if (episode.stremioId) {
episodeId = episode.stremioId;
} else {
const isImdb = id.startsWith('tt');
episodeId = isImdb
? `${id}:${episode.season_number}:${episode.episode_number}`
: `${id}:${episode.episode_number}`;
}
// Optimize navigation with requestAnimationFrame
requestAnimationFrame(() => {

View file

@ -325,8 +325,17 @@ class StremioService {
return true;
}
// Check if the ID matches any supported prefix
return supportedPrefixes.some(prefix => lowerId.startsWith(prefix.toLowerCase()));
// Check if the ID matches any supported prefix.
// For prefixes without a trailing separator (e.g. "mal", "kitsu"), the ID must be
// longer than the prefix itself so that bare prefix strings like "mal" are rejected.
const result = supportedPrefixes.some(prefix => {
const lowerPrefix = prefix.toLowerCase();
if (!lowerId.startsWith(lowerPrefix)) return false;
if (lowerPrefix.endsWith(':') || lowerPrefix.endsWith('_')) return true;
return lowerId.length > lowerPrefix.length;
});
if (__DEV__) console.log(`🔍 [isValidContentId] Prefix match result: ${result} for ID '${id}'`);
return result;
}
// Get all content types supported by installed addons

View file

@ -529,11 +529,16 @@ export class TMDBService {
*/
async extractTMDBIdFromStremioId(stremioId: string): Promise<number | null> {
try {
// Extract the base IMDB ID (remove season/episode info if present)
const imdbId = stremioId.split(':')[0];
// Extract the base ID (remove season/episode info if present)
const baseId = stremioId.split(':')[0];
// Only try to convert if it's an IMDb ID (starts with 'tt')
if (!baseId.startsWith('tt')) {
return null;
}
// Use the existing findTMDBIdByIMDB function to get the TMDB ID
const tmdbId = await this.findTMDBIdByIMDB(imdbId);
const tmdbId = await this.findTMDBIdByIMDB(baseId);
return tmdbId;
} catch (error) {
return null;