mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
Merge pull request #577 from skoruppa/main
fix for Kitsu and Mal content being still incorrectly requested
This commit is contained in:
commit
7d60a0c43f
4 changed files with 73 additions and 43 deletions
|
|
@ -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
|
// 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);
|
if (__DEV__) console.log('🔍 [loadEpisodeStreams] Getting TMDB ID for:', id);
|
||||||
let tmdbId;
|
let tmdbId;
|
||||||
let stremioEpisodeId = episodeId; // Default to original episode ID
|
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 cleanEpisodeId = episodeId.replace(/^series:/, '');
|
||||||
const parts = cleanEpisodeId.split(':');
|
const parts = cleanEpisodeId.split(':');
|
||||||
|
|
||||||
if (parts[0] === 'kitsu' && parts.length === 3) {
|
if (isImdb && parts.length === 3) {
|
||||||
// kitsu:animeId:episode — no season segment
|
// 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]}`;
|
showIdStr = `${parts[0]}:${parts[1]}`;
|
||||||
episodeNum = parts[2];
|
episodeNum = parts[2];
|
||||||
seasonNum = '';
|
seasonNum = '';
|
||||||
} else if (parts.length >= 3) {
|
|
||||||
episodeNum = parts.pop() || '';
|
|
||||||
seasonNum = parts.pop() || '';
|
|
||||||
showIdStr = parts.join(':');
|
|
||||||
} else if (parts.length === 2) {
|
} else if (parts.length === 2) {
|
||||||
showIdStr = parts[0];
|
showIdStr = parts[0];
|
||||||
episodeNum = parts[1];
|
episodeNum = parts[1];
|
||||||
seasonNum = '';
|
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}`);
|
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);
|
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
|
// This is already an IMDB ID, perfect for Stremio
|
||||||
if (settings.enrichMetadataWithTMDB) {
|
if (settings.enrichMetadataWithTMDB) {
|
||||||
if (__DEV__) console.log('📝 [loadEpisodeStreams] Converting IMDB ID to TMDB ID...');
|
if (__DEV__) console.log('📝 [loadEpisodeStreams] Converting IMDB ID to TMDB ID...');
|
||||||
|
|
|
||||||
|
|
@ -586,13 +586,17 @@ const MetadataScreen: React.FC = () => {
|
||||||
|
|
||||||
const handleShowStreams = useCallback(() => {
|
const handleShowStreams = useCallback(() => {
|
||||||
const { watchProgress } = watchProgressData;
|
const { watchProgress } = watchProgressData;
|
||||||
|
const isImdb = id.startsWith('tt');
|
||||||
|
|
||||||
// Ensure trailer stops immediately before navigating to Streams
|
// Ensure trailer stops immediately before navigating to Streams
|
||||||
try { pauseTrailer(); } catch { }
|
try { pauseTrailer(); } catch { }
|
||||||
|
|
||||||
// Helper to build episodeId from episode object
|
// Helper to build episodeId from episode object
|
||||||
const buildEpisodeId = (ep: any): string => {
|
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) {
|
if (Object.keys(groupedEpisodes).length > 0) {
|
||||||
|
|
@ -611,38 +615,28 @@ const MetadataScreen: React.FC = () => {
|
||||||
|
|
||||||
const parts = watchProgress.episodeId.split(':');
|
const parts = watchProgress.episodeId.split(':');
|
||||||
|
|
||||||
if (parts.length === 3) {
|
if (isImdb) {
|
||||||
// showId:season:episode
|
if (parts.length === 3) {
|
||||||
currentSeason = parseInt(parts[1], 10);
|
currentSeason = parseInt(parts[1], 10);
|
||||||
currentEpisode = parseInt(parts[2], 10);
|
currentEpisode = parseInt(parts[2], 10);
|
||||||
} else if (parts.length === 2) {
|
} else if (parts.length === 2) {
|
||||||
// season:episode
|
currentEpisode = parseInt(parts[1], 10);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
currentEpisode = parts.length === 3 ? parseInt(parts[2], 10) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentSeason !== null && currentEpisode !== null) {
|
if (currentEpisode !== null) {
|
||||||
// DIRECT APPROACH: Just create the next episode ID directly
|
const nextEpisodeId = isImdb
|
||||||
// This ensures we navigate to the next episode even if it's not yet in our episodes array
|
? `${id}:${currentSeason || episodes[0]?.season_number || 1}:${currentEpisode + 1}`
|
||||||
const nextEpisodeId = `${id}:${currentSeason}:${currentEpisode + 1}`;
|
: `${id}:${currentEpisode + 1}`;
|
||||||
if (__DEV__) console.log(`[MetadataScreen] Created next episode ID directly: ${nextEpisodeId}`);
|
if (__DEV__) console.log(`[MetadataScreen] Created next episode ID: ${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)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
const nextEpisodeExists = episodes.some(ep => ep.episode_number === (currentEpisode + 1));
|
||||||
if (nextEpisodeExists) {
|
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 {
|
} 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;
|
targetEpisodeId = nextEpisodeId;
|
||||||
|
|
@ -656,10 +650,14 @@ const MetadataScreen: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetEpisodeId) {
|
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(':');
|
const epParts = targetEpisodeId.split(':');
|
||||||
let normalizedEpisodeId = targetEpisodeId;
|
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]}`;
|
normalizedEpisodeId = `${id}:${epParts[0]}:${epParts[1]}`;
|
||||||
}
|
}
|
||||||
if (__DEV__) console.log(`[MetadataScreen] Navigating to streams with episodeId: ${normalizedEpisodeId}`);
|
if (__DEV__) console.log(`[MetadataScreen] Navigating to streams with episodeId: ${normalizedEpisodeId}`);
|
||||||
|
|
@ -672,7 +670,9 @@ const MetadataScreen: React.FC = () => {
|
||||||
let fallbackEpisodeId = episodeId;
|
let fallbackEpisodeId = episodeId;
|
||||||
if (episodeId && episodeId.split(':').length === 2) {
|
if (episodeId && episodeId.split(':').length === 2) {
|
||||||
const p = episodeId.split(':');
|
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}`);
|
if (__DEV__) console.log(`[MetadataScreen] Navigating with fallback episodeId: ${fallbackEpisodeId}`);
|
||||||
navigation.navigate('Streams', { id, type, episodeId: fallbackEpisodeId });
|
navigation.navigate('Streams', { id, type, episodeId: fallbackEpisodeId });
|
||||||
|
|
@ -682,7 +682,16 @@ const MetadataScreen: React.FC = () => {
|
||||||
if (!isScreenFocused) return;
|
if (!isScreenFocused) return;
|
||||||
|
|
||||||
if (__DEV__) console.log('[MetadataScreen] Selected Episode:', episode.episode_number, episode.season_number);
|
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
|
// Optimize navigation with requestAnimationFrame
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
|
|
|
||||||
|
|
@ -325,8 +325,17 @@ class StremioService {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the ID matches any supported prefix
|
// Check if the ID matches any supported prefix.
|
||||||
return supportedPrefixes.some(prefix => lowerId.startsWith(prefix.toLowerCase()));
|
// 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
|
// Get all content types supported by installed addons
|
||||||
|
|
|
||||||
|
|
@ -529,11 +529,16 @@ export class TMDBService {
|
||||||
*/
|
*/
|
||||||
async extractTMDBIdFromStremioId(stremioId: string): Promise<number | null> {
|
async extractTMDBIdFromStremioId(stremioId: string): Promise<number | null> {
|
||||||
try {
|
try {
|
||||||
// Extract the base IMDB ID (remove season/episode info if present)
|
// Extract the base ID (remove season/episode info if present)
|
||||||
const imdbId = stremioId.split(':')[0];
|
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
|
// Use the existing findTMDBIdByIMDB function to get the TMDB ID
|
||||||
const tmdbId = await this.findTMDBIdByIMDB(imdbId);
|
const tmdbId = await this.findTMDBIdByIMDB(baseId);
|
||||||
return tmdbId;
|
return tmdbId;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue