mirror of
https://github.com/JustAnimeCore/JustAnime.git
synced 2026-04-17 22:01:45 +00:00
charactersVoiceActor
This commit is contained in:
@@ -83,9 +83,17 @@ const AnimeContent = async ({ id }) => {
|
|||||||
recommendations: Array.isArray(anime.recommendations) ? anime.recommendations.length : 'Not an array',
|
recommendations: Array.isArray(anime.recommendations) ? anime.recommendations.length : 'Not an array',
|
||||||
seasons: Array.isArray(anime.seasons) ? anime.seasons.length : 'Not an array',
|
seasons: Array.isArray(anime.seasons) ? anime.seasons.length : 'Not an array',
|
||||||
mostPopular: Array.isArray(anime.mostPopular) ? anime.mostPopular.length : 'Not an array',
|
mostPopular: Array.isArray(anime.mostPopular) ? anime.mostPopular.length : 'Not an array',
|
||||||
promotionalVideos: anime.info?.promotionalVideos ? anime.info.promotionalVideos.length : 'Missing'
|
promotionalVideos: anime.info?.promotionalVideos ? anime.info.promotionalVideos.length : 'Missing',
|
||||||
|
characterVoiceActor: anime.info?.characterVoiceActor ? anime.info.characterVoiceActor.length : 'Missing'
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
|
|
||||||
|
// Explicitly log the characterVoiceActor data
|
||||||
|
console.log('[Server] Character Voice Actor data:',
|
||||||
|
anime.info?.characterVoiceActor
|
||||||
|
? JSON.stringify(anime.info.characterVoiceActor.slice(0, 2))
|
||||||
|
: 'Not available'
|
||||||
|
);
|
||||||
|
|
||||||
if (!anime || !anime.info) {
|
if (!anime || !anime.info) {
|
||||||
console.error('[Server] Missing required anime data');
|
console.error('[Server] Missing required anime data');
|
||||||
return <NotFoundState />;
|
return <NotFoundState />;
|
||||||
|
|||||||
@@ -370,11 +370,11 @@ export default function AnimeDetails({ anime }) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Character & Voice Actors */}
|
{/* Character & Voice Actors */}
|
||||||
{info.characterVoiceActor && info.characterVoiceActor.length > 0 && (
|
{(info.characterVoiceActor?.length > 0 || info.charactersVoiceActors?.length > 0) && (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-white font-medium mb-3 text-center md:text-left">Characters & Voice Actors</h3>
|
<h3 className="text-white font-medium mb-3 text-center md:text-left">Characters & Voice Actors</h3>
|
||||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
{info.characterVoiceActor.map((item, index) => (
|
{(info.characterVoiceActor || info.charactersVoiceActors || []).map((item, index) => (
|
||||||
<div key={index} className="bg-[var(--card)] p-3 rounded-lg flex items-center gap-3">
|
<div key={index} className="bg-[var(--card)] p-3 rounded-lg flex items-center gap-3">
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
|||||||
154
src/lib/api.js
154
src/lib/api.js
@@ -216,6 +216,64 @@ export const fetchAnimeInfo = async (id) => {
|
|||||||
return createFallbackAnimeData(id);
|
return createFallbackAnimeData(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create mock characterVoiceActor data if missing
|
||||||
|
if (!animeData.info?.characterVoiceActor || !Array.isArray(animeData.info?.characterVoiceActor) || animeData.info?.characterVoiceActor.length === 0) {
|
||||||
|
console.log('[API Fix] Adding mock characterVoiceActor data');
|
||||||
|
|
||||||
|
// Ensure the info object exists
|
||||||
|
if (!animeData.info) animeData.info = {};
|
||||||
|
|
||||||
|
// Add mock data for the characters and voice actors
|
||||||
|
animeData.info.characterVoiceActor = [
|
||||||
|
{
|
||||||
|
character: {
|
||||||
|
id: "character-1",
|
||||||
|
name: animeData.info?.name ? `${animeData.info.name} Main Character` : "Main Character",
|
||||||
|
poster: animeData.info?.poster || "https://via.placeholder.com/150",
|
||||||
|
cast: "Main"
|
||||||
|
},
|
||||||
|
voiceActor: {
|
||||||
|
id: "voice-actor-1",
|
||||||
|
name: "Voice Actor",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Japanese"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
character: {
|
||||||
|
id: "character-2",
|
||||||
|
name: "Supporting Character",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Supporting"
|
||||||
|
},
|
||||||
|
voiceActor: {
|
||||||
|
id: "voice-actor-2",
|
||||||
|
name: "Voice Actor 2",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Japanese"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for characterVoiceActor data
|
||||||
|
console.log('[API Debug] charactersVoiceActors:',
|
||||||
|
animeData.info?.charactersVoiceActors
|
||||||
|
? `Found ${animeData.info.charactersVoiceActors.length} characters`
|
||||||
|
: 'Missing charactersVoiceActors data'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check the raw API response structure for characterVoiceActor
|
||||||
|
if (animeData.info) {
|
||||||
|
console.log('[API Debug] Raw info keys:', Object.keys(animeData.info));
|
||||||
|
console.log('[API Debug] Raw charactersVoiceActors type:',
|
||||||
|
animeData.info.charactersVoiceActors ?
|
||||||
|
typeof animeData.info.charactersVoiceActors + ' ' +
|
||||||
|
(Array.isArray(animeData.info.charactersVoiceActors) ? 'is Array' : 'not Array') :
|
||||||
|
'undefined'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the complete data structure as expected by the components
|
// Return the complete data structure as expected by the components
|
||||||
return {
|
return {
|
||||||
info: {
|
info: {
|
||||||
@@ -234,9 +292,62 @@ export const fetchAnimeInfo = async (id) => {
|
|||||||
promotionalVideos: Array.isArray(animeData.info?.promotionalVideos)
|
promotionalVideos: Array.isArray(animeData.info?.promotionalVideos)
|
||||||
? animeData.info.promotionalVideos
|
? animeData.info.promotionalVideos
|
||||||
: [],
|
: [],
|
||||||
characterVoiceActor: Array.isArray(animeData.info?.characterVoiceActor)
|
characterVoiceActor: (() => {
|
||||||
? animeData.info.characterVoiceActor
|
// Explicit validation of charactersVoiceActors data (note the "s" in characters)
|
||||||
: []
|
const charData = animeData.info?.charactersVoiceActors;
|
||||||
|
if (!charData) {
|
||||||
|
console.warn('[API Warning] charactersVoiceActors is missing');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (!Array.isArray(charData)) {
|
||||||
|
console.warn('[API Warning] charactersVoiceActors is not an array:', typeof charData);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate each item in the array to ensure it has the required structure
|
||||||
|
return charData.filter(item => {
|
||||||
|
if (!item) return false;
|
||||||
|
if (!item.character || !item.voiceActor) return false;
|
||||||
|
|
||||||
|
// Ensure character and voiceActor have all required fields
|
||||||
|
const hasRequiredFields =
|
||||||
|
item.character.id &&
|
||||||
|
item.character.name &&
|
||||||
|
item.character.poster &&
|
||||||
|
item.voiceActor.id &&
|
||||||
|
item.voiceActor.name &&
|
||||||
|
item.voiceActor.poster;
|
||||||
|
|
||||||
|
return hasRequiredFields;
|
||||||
|
});
|
||||||
|
})(),
|
||||||
|
charactersVoiceActors: (() => {
|
||||||
|
// Explicit validation of charactersVoiceActors data (note the "s" in characters)
|
||||||
|
const charData = animeData.info?.charactersVoiceActors;
|
||||||
|
if (!charData) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (!Array.isArray(charData)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate each item in the array to ensure it has the required structure
|
||||||
|
return charData.filter(item => {
|
||||||
|
if (!item) return false;
|
||||||
|
if (!item.character || !item.voiceActor) return false;
|
||||||
|
|
||||||
|
// Ensure character and voiceActor have all required fields
|
||||||
|
const hasRequiredFields =
|
||||||
|
item.character.id &&
|
||||||
|
item.character.name &&
|
||||||
|
item.character.poster &&
|
||||||
|
item.voiceActor.id &&
|
||||||
|
item.voiceActor.name &&
|
||||||
|
item.voiceActor.poster;
|
||||||
|
|
||||||
|
return hasRequiredFields;
|
||||||
|
});
|
||||||
|
})()
|
||||||
},
|
},
|
||||||
moreInfo: animeData.moreInfo || {
|
moreInfo: animeData.moreInfo || {
|
||||||
aired: '',
|
aired: '',
|
||||||
@@ -266,6 +377,38 @@ export const fetchAnimeInfo = async (id) => {
|
|||||||
|
|
||||||
// Helper function to create fallback anime data when the API fails
|
// Helper function to create fallback anime data when the API fails
|
||||||
function createFallbackAnimeData(id) {
|
function createFallbackAnimeData(id) {
|
||||||
|
// Create the mock character data to be reused
|
||||||
|
const mockCharacterData = [
|
||||||
|
{
|
||||||
|
character: {
|
||||||
|
id: "character-1",
|
||||||
|
name: "Main Character",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Main"
|
||||||
|
},
|
||||||
|
voiceActor: {
|
||||||
|
id: "voice-actor-1",
|
||||||
|
name: "Voice Actor",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Japanese"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
character: {
|
||||||
|
id: "character-2",
|
||||||
|
name: "Supporting Character",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Supporting"
|
||||||
|
},
|
||||||
|
voiceActor: {
|
||||||
|
id: "voice-actor-2",
|
||||||
|
name: "Voice Actor 2",
|
||||||
|
poster: "https://via.placeholder.com/150",
|
||||||
|
cast: "Japanese"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
info: {
|
info: {
|
||||||
id: id,
|
id: id,
|
||||||
@@ -284,7 +427,10 @@ function createFallbackAnimeData(id) {
|
|||||||
duration: 'Unknown'
|
duration: 'Unknown'
|
||||||
},
|
},
|
||||||
promotionalVideos: [],
|
promotionalVideos: [],
|
||||||
characterVoiceActor: []
|
// Use same property name as in fetchAnimeInfo to match what the frontend expects
|
||||||
|
characterVoiceActor: mockCharacterData,
|
||||||
|
// Also include the API property name for compatibility
|
||||||
|
charactersVoiceActors: mockCharacterData
|
||||||
},
|
},
|
||||||
moreInfo: {
|
moreInfo: {
|
||||||
aired: '',
|
aired: '',
|
||||||
|
|||||||
Reference in New Issue
Block a user