code organisation & refactor
This commit is contained in:
178
src/scripts/anime/anime.js
Normal file
178
src/scripts/anime/anime.js
Normal file
@@ -0,0 +1,178 @@
|
||||
const animeId = window.location.pathname.split('/').pop();
|
||||
let player;
|
||||
|
||||
let totalEpisodes = 0;
|
||||
let currentPage = 1;
|
||||
const itemsPerPage = 12;
|
||||
|
||||
var tag = document.createElement('script');
|
||||
tag.src = "https://www.youtube.com/iframe_api";
|
||||
var firstScriptTag = document.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
|
||||
async function loadAnime() {
|
||||
try {
|
||||
const res = await fetch(`/api/anime/${animeId}`);
|
||||
const data = await res.json();
|
||||
|
||||
if(data.error) {
|
||||
document.getElementById('title').innerText = "Anime Not Found";
|
||||
return;
|
||||
}
|
||||
|
||||
const title = data.title.english || data.title.romaji;
|
||||
document.title = `${title} | WaifuBoard`;
|
||||
document.getElementById('title').innerText = title;
|
||||
document.getElementById('poster').src = data.coverImage.extraLarge;
|
||||
|
||||
const rawDesc = data.description || "No description available.";
|
||||
handleDescription(rawDesc);
|
||||
|
||||
document.getElementById('score').innerText = (data.averageScore || '?') + '% Score';
|
||||
document.getElementById('year').innerText = data.seasonYear || '????';
|
||||
document.getElementById('genres').innerText = data.genres ? data.genres.slice(0, 3).join(' • ') : '';
|
||||
|
||||
document.getElementById('format').innerText = data.format || 'TV';
|
||||
document.getElementById('episodes').innerText = data.episodes || '?';
|
||||
document.getElementById('status').innerText = data.status || 'Unknown';
|
||||
document.getElementById('season').innerText = `${data.season || ''} ${data.seasonYear || ''}`;
|
||||
|
||||
if (data.studios && data.studios.nodes.length > 0) {
|
||||
document.getElementById('studio').innerText = data.studios.nodes[0].name;
|
||||
}
|
||||
|
||||
if (data.characters && data.characters.nodes) {
|
||||
const charContainer = document.getElementById('char-list');
|
||||
data.characters.nodes.slice(0, 5).forEach(char => {
|
||||
charContainer.innerHTML += `
|
||||
<div class="character-item">
|
||||
<div class="char-dot"></div> ${char.name.full}
|
||||
</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('watch-btn').onclick = () => {
|
||||
window.location.href = `/watch/${animeId}/1`;
|
||||
};
|
||||
|
||||
if (data.trailer && data.trailer.site === 'youtube') {
|
||||
window.onYouTubeIframeAPIReady = function() {
|
||||
player = new YT.Player('player', {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
videoId: data.trailer.id,
|
||||
playerVars: {
|
||||
'autoplay': 1, 'controls': 0, 'mute': 1,
|
||||
'loop': 1, 'playlist': data.trailer.id,
|
||||
'showinfo': 0, 'modestbranding': 1, 'disablekb': 1
|
||||
},
|
||||
events: { 'onReady': (e) => e.target.playVideo() }
|
||||
});
|
||||
};
|
||||
} else {
|
||||
const banner = data.bannerImage || data.coverImage.extraLarge;
|
||||
document.querySelector('.video-background').innerHTML = `<img src="${banner}" style="width:100%; height:100%; object-fit:cover;">`;
|
||||
}
|
||||
|
||||
|
||||
if (data.nextAiringEpisode) {
|
||||
totalEpisodes = data.nextAiringEpisode.episode - 1;
|
||||
} else {
|
||||
totalEpisodes = data.episodes || 12;
|
||||
}
|
||||
|
||||
totalEpisodes = Math.min(Math.max(totalEpisodes, 1), 5000);
|
||||
|
||||
renderEpisodes();
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
function handleDescription(text) {
|
||||
const tmp = document.createElement("DIV");
|
||||
tmp.innerHTML = text;
|
||||
const cleanText = tmp.textContent || tmp.innerText || "";
|
||||
|
||||
const sentences = cleanText.match(/[^\.!\?]+[\.!\?]+/g) || [cleanText];
|
||||
|
||||
document.getElementById('full-description').innerHTML = text;
|
||||
|
||||
if (sentences.length > 4) {
|
||||
const shortText = sentences.slice(0, 4).join(' ');
|
||||
document.getElementById('description-preview').innerText = shortText + '...';
|
||||
document.getElementById('read-more-btn').style.display = 'inline-flex';
|
||||
} else {
|
||||
document.getElementById('description-preview').innerHTML = text;
|
||||
document.getElementById('read-more-btn').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function openModal() {
|
||||
document.getElementById('desc-modal').classList.add('active');
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('desc-modal').classList.remove('active');
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
|
||||
document.getElementById('desc-modal').addEventListener('click', (e) => {
|
||||
if (e.target.id === 'desc-modal') closeModal();
|
||||
});
|
||||
|
||||
function renderEpisodes() {
|
||||
const grid = document.getElementById('episodes-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
const start = (currentPage - 1) * itemsPerPage + 1;
|
||||
const end = Math.min(start + itemsPerPage - 1, totalEpisodes);
|
||||
|
||||
for(let i = start; i <= end; i++) {
|
||||
createEpisodeButton(i, grid);
|
||||
}
|
||||
updatePaginationControls();
|
||||
}
|
||||
|
||||
function createEpisodeButton(num, container) {
|
||||
const btn = document.createElement('div');
|
||||
btn.className = 'episode-btn';
|
||||
btn.innerText = `Ep ${num}`;
|
||||
btn.onclick = () => window.location.href = `/watch/${animeId}/${num}`;
|
||||
container.appendChild(btn);
|
||||
}
|
||||
|
||||
function updatePaginationControls() {
|
||||
const totalPages = Math.ceil(totalEpisodes / itemsPerPage);
|
||||
document.getElementById('page-info').innerText = `Page ${currentPage} of ${totalPages}`;
|
||||
document.getElementById('prev-page').disabled = currentPage === 1;
|
||||
document.getElementById('next-page').disabled = currentPage === totalPages;
|
||||
|
||||
document.getElementById('pagination-controls').style.display = 'flex';
|
||||
}
|
||||
|
||||
function changePage(delta) {
|
||||
currentPage += delta;
|
||||
renderEpisodes();
|
||||
}
|
||||
|
||||
const searchInput = document.getElementById('ep-search');
|
||||
searchInput.addEventListener('input', (e) => {
|
||||
const val = parseInt(e.target.value);
|
||||
const grid = document.getElementById('episodes-grid');
|
||||
|
||||
if (val > 0 && val <= totalEpisodes) {
|
||||
grid.innerHTML = '';
|
||||
createEpisodeButton(val, grid);
|
||||
document.getElementById('pagination-controls').style.display = 'none';
|
||||
} else if (!e.target.value) {
|
||||
renderEpisodes();
|
||||
} else {
|
||||
grid.innerHTML = '<div style="color:#666; width:100%; text-align:center;">Episode not found</div>';
|
||||
document.getElementById('pagination-controls').style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
loadAnime();
|
||||
Reference in New Issue
Block a user