Organized the differences between server and docker versions.
We are launching a docker version (server version) today so we want to just organize the repo so its easier to navigate.
This commit is contained in:
134
docker/src/scripts/books/books.js
Normal file
134
docker/src/scripts/books/books.js
Normal file
@@ -0,0 +1,134 @@
|
||||
let trendingBooks = [];
|
||||
let currentHeroIndex = 0;
|
||||
let heroInterval;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
SearchManager.init('#search-input', '#search-results', 'book');
|
||||
ContinueWatchingManager.load('my-status-books', 'reading', 'MANGA');
|
||||
init();
|
||||
});
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('navbar');
|
||||
if (window.scrollY > 50) nav.classList.add('scrolled');
|
||||
else nav.classList.remove('scrolled');
|
||||
});
|
||||
|
||||
function scrollCarousel(id, direction) {
|
||||
const container = document.getElementById(id);
|
||||
if(container) {
|
||||
const scrollAmount = container.clientWidth * 0.75;
|
||||
container.scrollBy({ left: direction * scrollAmount, behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
try {
|
||||
const res = await fetch('/api/books/trending');
|
||||
const data = await res.json();
|
||||
|
||||
if (data.results && data.results.length > 0) {
|
||||
trendingBooks = data.results;
|
||||
updateHeroUI(trendingBooks[0]);
|
||||
renderList('trending', trendingBooks);
|
||||
startHeroCycle();
|
||||
}
|
||||
|
||||
const resPop = await fetch('/api/books/popular');
|
||||
const dataPop = await resPop.json();
|
||||
if (dataPop.results) renderList('popular', dataPop.results);
|
||||
|
||||
} catch (e) {
|
||||
console.error("Books Error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
function startHeroCycle() {
|
||||
if(heroInterval) clearInterval(heroInterval);
|
||||
heroInterval = setInterval(() => {
|
||||
if(trendingBooks.length > 0) {
|
||||
currentHeroIndex = (currentHeroIndex + 1) % trendingBooks.length;
|
||||
updateHeroUI(trendingBooks[currentHeroIndex]);
|
||||
}
|
||||
}, 8000);
|
||||
}
|
||||
|
||||
async function updateHeroUI(book) {
|
||||
if(!book) return;
|
||||
|
||||
const title = book.title.english || book.title.romaji;
|
||||
const desc = book.description || "No description available.";
|
||||
const poster = (book.coverImage && (book.coverImage.extraLarge || book.coverImage.large)) || '';
|
||||
const banner = book.bannerImage || poster;
|
||||
|
||||
document.getElementById('hero-title').innerText = title;
|
||||
document.getElementById('hero-desc').innerHTML = desc;
|
||||
document.getElementById('hero-score').innerText = (book.averageScore || '?') + '% Score';
|
||||
document.getElementById('hero-year').innerText = (book.startDate && book.startDate.year) ? book.startDate.year : '????';
|
||||
document.getElementById('hero-type').innerText = book.format || 'MANGA';
|
||||
|
||||
const heroPoster = document.getElementById('hero-poster');
|
||||
if(heroPoster) heroPoster.src = poster;
|
||||
|
||||
const bg = document.getElementById('hero-bg-media');
|
||||
if(bg) bg.src = banner;
|
||||
|
||||
const readBtn = document.getElementById('read-btn');
|
||||
if (readBtn) {
|
||||
readBtn.onclick = () => window.location.href = `/book/${book.id}`;
|
||||
}
|
||||
|
||||
const addToListBtn = document.querySelector('.hero-buttons .btn-blur');
|
||||
if(addToListBtn) {
|
||||
ListModalManager.currentData = book;
|
||||
const entryType = ListModalManager.getEntryType(book);
|
||||
|
||||
await ListModalManager.checkIfInList(book.id, 'anilist', entryType);
|
||||
ListModalManager.updateButton();
|
||||
|
||||
addToListBtn.onclick = () => ListModalManager.open(book, 'anilist');
|
||||
}
|
||||
}
|
||||
|
||||
function renderList(id, list) {
|
||||
const container = document.getElementById(id);
|
||||
container.innerHTML = '';
|
||||
|
||||
list.forEach(book => {
|
||||
const title = book.title.english || book.title.romaji;
|
||||
const cover = book.coverImage ? book.coverImage.large : '';
|
||||
const score = book.averageScore || '--';
|
||||
const type = book.format || 'Book';
|
||||
|
||||
const el = document.createElement('div');
|
||||
el.className = 'card';
|
||||
|
||||
el.onclick = () => {
|
||||
window.location.href = `/book/${book.id}`;
|
||||
};
|
||||
el.innerHTML = `
|
||||
<div class="card-img-wrap"><img src="${cover}" loading="lazy"></div>
|
||||
<div class="card-content">
|
||||
<h3>${title}</h3>
|
||||
<p>${score}% • ${type}</p>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(el);
|
||||
});
|
||||
}
|
||||
|
||||
function saveToList() {
|
||||
const bookId = ListModalManager.currentData ? ListModalManager.currentData.id : null;
|
||||
if (!bookId) return;
|
||||
ListModalManager.save(bookId, 'anilist');
|
||||
}
|
||||
|
||||
function deleteFromList() {
|
||||
const bookId = ListModalManager.currentData ? ListModalManager.currentData.id : null;
|
||||
if (!bookId) return;
|
||||
ListModalManager.delete(bookId, 'anilist');
|
||||
}
|
||||
|
||||
function closeAddToListModal() {
|
||||
ListModalManager.close();
|
||||
}
|
||||
Reference in New Issue
Block a user